RandyTek
RandyTek

Reputation: 4744

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.

Upvotes: 15

Views: 12244

Answers (2)

retgoat
retgoat

Reputation: 2464

Try this as a possible way:

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

You can find more examples here

Upvotes: 2

Dave Schweisguth
Dave Schweisguth

Reputation: 37607

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.

Upvotes: 21

Related Questions