I'm using rspec-spies and am wondering if there's a way to inspect a spy after all the calls have been made.
For example, If I do something like
# setup
Post.stub(:find).with(@post.id).and_return(@post)
do_something_to_call_post_find()
# verify find was called
Post.should have_received(:find).with(@post.id)
This works great, but if Post didn't receive the expected argument, I get an unhelpful error message (basically "Post should have received find with 123"). Instead, I'd like to see what the actual calls to `find
were.
I can pause right after do_something_to_call_post_find()
, but is there a way to list all the calls / arguments to a stub/spy?
Actual use case
This one caught me up today -- I was expecting Post.should have_received(:find).with(@post.id)
, where @post.id is an integer
, my controller test passes the params (including the id) as a string. If I could have inspected the actual calls, I would have seen the difference between 123
and "123"
and it would have been obvious.
This shortfall is no longer an issue in rspec 2.14.0.rc1, which incorporates the improved rspec-spies functionality and is available now on github.
For example, executing the following spec:
class Foo
def self.bar(arg)
end
end
describe "test" do
it "should show differences" do
Foo.stub(:bar)
Foo.bar(123)
Foo.should have_received(:bar).with('123')
end
end
generates the following output:
F
Failures:
1) test should show differences
Failure/Error: Foo.should have_received(:bar).with('123')
<Foo (class)> received :bar with unexpected arguments
expected: ("123")
got: (123)
# ./foo_spec.rb:10:in `block (2 levels) in <top (required)>'
Finished in 0.00082 seconds
1 example, 1 failure
Failed examples:
rspec ./foo_spec.rb:7 # test should show differences
Peters-MacBook-Air-2:botmetrics palfvin$
Update: Based on an examination of the definition of the have_received
matcher at https://github.com/technicalpickles/rspec-spies/blob/master/lib/rspec-spies.rb and some informal testing, it appears that the messages received can be accessed programmatically as follows:
Foo.__send__(:__mock_proxy).instance_variable_get("@messages_received")
where Foo
is your test double.