On 7 Jun 2010, at 15:56, Ben Butler-Cole wrote:

> 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.

I'm still not quite clear what you're trying to achieve. Do you want to assert 
that a specific block is passed to the collaborator, or do you want to assert 
that any old block with a particular behaviour is passed to the collaborator?

If it's the former, you can test it by creating a test double for the block, 
and asserting that it's passed to the collaborator, like this:
http://gist.github.com/428801

Does that help?


> 
> -Ben
> 
> _______________________________________________
> rspec-users mailing list
> rspec-users@rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users

_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to