If anyone is interested, I wrote a quick little gem to add spies to
rspec-mocks. Basically, it adds a method called spy which internally
returns
a mock.as_null_object, and a matcher for “have_received(:method)” &
“have_received(:method).with(args)”.
David, my understanding of your point (or at least, part of it) is that
you’d rather use mocks since they fail on the method calls that have
never
been set up. The way I see it, if I want something to fail I’d rather
make
it explicit. I’d rather explicitly state that “object.should_not
have_received(:wrong_method)” so that the test is perfectly clear, than
want
to use a standard mock which would fail . This is the same reason I
imagine
we have “lambda {a_call}.should_not raise_error”. We don’t really need
that
since the test fails because of an exception nonetheless. Of course,
mocks
would also work as a general check against calls to other methods.
The last time I used something like this (when using RhinoMocks working
on a
.net project) if you had to have a return (that your production code
would
use) you would set up the expectation before hand with a
:should_receive.
You would only use the :have_received matcher on calls that you didn’t
need
to set an expectation on. Even though this might be seem to be a little
consistent, with a little of this and a little of that, it worked out
quite
well on us, with the added benefit of not needing stubs on methods where
the
return value doesn’t matter and you saving a little bit of noise in your
tests.
Nonetheless, here’s the gem: stirlitz | RubyGems.org | your community gem host
Thanks,
Srushti
[moved your post to the bottom for consistency with this thread]
On Mar 23, 2011, at 1:41 PM, Srushti wrote:
user = User.new
foo.should_receive(:bar).and_return(:baz)
foo.stub(:bar).with(:baz).and_return(:bam)
… because calling bar(:anything_other_than_baz) would not work due to the
with() constraint.
rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users
This is a long-running discussion and I suspect it comes down to personal
preference in the end more than anything else. However, I have done some work to
get a basic test spy library working with rspec which tries to avoid unnecessary
stubbing to allow assertion on method calls (i.e. you only need to set up a stub
as well when you need to manipulate the return value). It’s in its infant stages
and needs some TLC (in particular, its factory method ‘spy’ is in the global
namespace, when it could and should be dealt with more elegantly), but it may be
of some use for test spy fanatics… GitHub - rentalcustard/matahari: Test spy library for Ruby
Thanks, Tom. Let me know if there is anything you need in RSpec to make it easy
to plug this in.
If anyone is interested, I wrote a quick little gem to add spies to rspec-mocks.
Basically, it adds a method called spy which internally returns a
mock.as_null_object, and a matcher for “have_received(:method)” &
“have_received(:method).with(args)”.
David, my understanding of your point (or at least, part of it) is that you’d
rather use mocks since they fail on the method calls that have never been set up.
That’s not what I said. Please re-read my examples above - they are
about the cases where a stubbed return value matters for the code to
run, which happens much more often than it would if we all followed
Tell, Don’t Ask (but we don’t so much).
On 24/03/11 12:29 AM, David C. wrote:
<mailto:[email protected]>>
>
>>> ExternalService.stub!(:new).and_return(service)
another mocking library which did something quite close to
http://groups.google.com/group/rspec/search?group=rspec&q=test+spies&qt_g=Search+this+group
>> foo(:bar)
>> foo.should_have_received(:bar)
work due to the with() constraint.
>> That said, if anyone cares to write an external library to
> This is a long-running discussion and I suspect it comes down
Thanks, Tom. Let me know if there is anything you need in RSpec
have never been set up.
reason I imagine we have “lambda {a_call}.should_not raise_error”. We
added benefit of not needing stubs on methods where the return value
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users
I guess you’re right, and I take back that point.
I haven’t used test spies in a while, so I might get back to you on this
in a while (I’m going to start using it whenever I can now), but I guess
it’s a matter of how often you depend on a return value. Your experience
seems to be, most of the time, or at least often enough that it doesn’t
make sense to add test spies. You’re probably right, but I’ll give it a
go nonetheless. There have been at least a few times that I’ve wished I
had access to test spies. These might have been rare occurrences and not
enough to justify polluting the api with a different type of asserting
on calls. On the other hand, I might have just gotten used to working
with rspec-mocks over time to stop looking for those types of usages
(which I used to see enough of when working in other languages & mocking
frameworks).
Regardless, I’ll report back in a while fighting for inclusion again, or
admitting everything’s fine the way it is.
Thanks,
Srushti