rspec-mocks' expect(target).to receive(:message).with(arg_matcher)
will only show an error at the end of the test if the target is invoked with parameters not matching the arg matcher passed to with
. Is there a way to force it to fail eagerly - i.e., as soon as the target is invoked with non-matching params? RR works in this way.
The problem I am facing is that when I set up this mock with an arg_matcher as above, the test starts failing because the target is called with different params, but then another assertion fails before the end of the test, so I only see the error from this assertion, not from the missing mock (which would have shown me the difference between the expected params and the actually invoked ones).
Using rspec-mocks 3.3.2.
I don't know of a way to make receive
fail eagerly. However, have_received
fails eagerly, so if it is the first of several expectations it will be the one that fails the test and that RSpec reports.
class Foo
def self.bar(baz)
end
end
describe "RSpec" do
it "reports a non-mock expectation failure before a mock expectation failure" do
expect(Foo).to receive(:bar).with(1)
expect(true).to be_falsy # RSpec reports this failure
Foo.bar 2
end
it "reports a spy expectation failure when you'd expect it to be reported" do
allow(Foo).to receive(:bar) # Spy on Foo
Foo.bar 2
expect(Foo).to have_received(:bar).with(1) # RSpec reports this failure
expect(true).to be_falsy
end
end
See the documentation of RSpec spies for details.
This solution is probably best if
allow
that sets up the spy less than you mind the aggregate_failures
blockRegular mocks and Adarsh's solution are better
aggregate_failures
block less than you mind the extra typing of the allow
that sets up the spy