On 7 June 2010 15:25, Matt Wynne <m...@mattwynne.net> wrote: Have you seen and_yield? I can't quite get my head around what you're trying > to do, but it might help anyway >
Thank you, I have. My understanding is that #and_yield has much the same use as #and_return (in its non-bastardized-by-me-form). That is, you specify it in order to make the mocked-out collaborator behave enough like the real collaborator that the object-under-test can work properly. I'll try to explain what I'm aiming for more comprehensibly. If I my object-under-test calls a method with a parameter, I can make assertions against the values passed. The simplest is equality: foo.should_receive(:bar).with(6) The corresponding code in the object-under-test is foo.bar(6) and the real code for the collaborator is something like: class Foo def bar(x) // ... end end Now the collaborator in my case doesn't take a parameter, it takes a block: class Foo2 def bar2(&block) // ... end end and the object-under-test passes in a block which is called later for its return value: foo2.bar2 { 6 } (The real block doesn't return a constant, obviously. It returns something which needs to be evaluated lazily because its dependencies don't exist yet.) I want to test that the block passed in is the block that I expect. Something like (in an imaginary world): foo2.should_receive(:foo2).with(block(yielding(6))) (In fact, in my case I can't just assert equality on the return value from the block. I'm actually going to test its type.) The corresponding test using my obscene #and_return hack looks like this: foo2.should_receive(:foo2).and_return { |block| block.call.should ==6 } But this doesn't scale to multiple calls to #foo2 in the object under test because RSpec (understandably) matches its expectations against invocations based on method name and argument matchers. -Ben
_______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users