[rspec-users] What is the best way to verify that yield is called?

Ben Mabey ben at benmabey.com
Wed Apr 9 14:15:31 EDT 2008


David Chelimsky wrote:
> On Wed, Apr 9, 2008 at 12:33 PM, Rick DeNatale <rick.denatale at gmail.com> wrote:
>   
>> On Wed, Apr 9, 2008 at 11:54 AM, David Chelimsky <dchelimsky at gmail.com> wrote:
>>
>>  >  What are you looking to specify and how do you envision the syntax?
>>  >
>>  >  I'm thinking something like:
>>  >
>>  >  obj.should yield_with(no_args).on(:message)
>>  >
>>  >  def message
>>  >   yield
>>  >  end
>>  >
>>  >  list.should yield_with(1).then(2).then(3).on(:each)
>>  >
>>  >  def each
>>  >   yield 1
>>  >   yield 2
>>  >   yield 3
>>  >  end
>>  >
>>  >  That all make sense?
>>
>>  Sorta, but what about arguments to the message?
>>
>>  def message(x, y, z)
>>    yield x+y+z
>>  end
>>
>>  obj.receiving(:message).with(1,2,3).should yield(6)
>>
>>  (1..3).receiving(:each_with_index).should
>>  yield_with([1,0]).then([2,1]).then([3,2])
>>
>>  or
>>
>>  (1..3).receiving(:each_with_index).should yield_with([1,0],([2,1],[3,2])
>>
>>  (1..3).receiving(:inject).with(0).should yield_with  ???????
>>
>>  Now it gets tricky since the sequence of yielded values depends on the block .
>>
>>  I don't know that I like where this is going.
>>     
>
> Agreed, this could get hairy. Perhaps we should chalk this up to
> implementation detail?
>
> Looking back at the OP:
>
> it "should yield a message_delivery object" do
>   create_message_in_factory do |message_delivery|
>     message_delivery.should be_instance_of(MessageDelivery)
>   end
> end
>
> How about something more like this as an idiom:
>
> it "should yield a message_delivery object" do
>   create_message_in_factory do |message_delivery|
>     return message_delivery
>   end.should be_instance_of(MessageDelivery)
> end
>   

That makes sense for the cases when an object is yielded but what would 
you do if no object is yielded and the block is just suppose to execute?

I guess you could do:

      it "should yield the given block" do
        some_method do
          return 42
        end.should == 42
      end

But this does not look any better than the two previously suggested ways IMO.  


> This still uses the contents of the blog to set an expectation, but is
> perhaps more expressive about the fact that we're not really
> interested in the contents of the block as much as we are what the end
> result is.
>
> WDYT?
>   

In the case where the an object is yielded I do like you suggestion because it covers everything.  I just don't know about when no object is yielded.

I guess if a matcher is not possible I will have to settle for one of 
the approaches above when no object is yielded.

Any more thoughts on the subject?

Thanks,

Ben


More information about the rspec-users mailing list