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

Reply via email to