Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In RSpec, how to expect multiple messages with different parameters in any order?

RSpec seems to match messages received by a method in order. I am not sure how to make the following code work:

allow(a).to receive(:f)
expect(a).to receive(:f).with(2)
a.f(1)
a.f(2)
a.f(3)

The reason I am asking is that some calls of a.f are controlled by an upper layer of my code, so I cannot add expectations to these method calls.

like image 887
RandyTek Avatar asked May 06 '16 00:05

RandyTek


2 Answers

RSpec spies are a way to test this situation. To spy on a method, stub it with allow with no constraints other than the method name, call the method, and expect the exact method calls afterwards.

For example:

allow(a).to receive(:f)
a.f(2)
a.f(1)
a.f(3)
expect(a).to have_received(:f).exactly(3).times
[1, 2, 3].each do |arg|
  expect(a).to have_received(:f).with(arg)
end

As you can see, this way of expecting method calls doesn't impose an order.

like image 160
Dave Schweisguth Avatar answered Nov 15 '22 17:11

Dave Schweisguth


Try this as a possible way:

expect(a).to receive(:f).at_most(3).times

You can find more examples here

like image 45
retgoat Avatar answered Nov 15 '22 17:11

retgoat