RSpec: Stubbing a method that takes a block

Updated . Posted . Visible to the public.

If you stub a method or set expectations with should_receive these stubbed methods may also yield blocks. This is handy if the returning object is receiving a block call.

Consider this, where you cannot say and_return [] because of the block:

def crawl_messages
  Message.find_in_batches do |messages|
    messages.each(&:crawl)
  end
end

It works similar to and_return -- just use and_yield Show archive.org snapshot :

describe '#crawl_messages' do
  it 'should process messages in batches so the server stays alive' do
    message = stub
    message.should_receive(:crawl)
    Message.should_receive(:find_in_batches).and_yield([message])
    subject.crawl_messages
  end
end

You can also combine and_yield with and_return. Mind the order:

item = stub('a block')
subject.should_receive(:something).and_yield(item).and_return 'result'

Yielding multiple times

You can even chain multiple and_yield statements to yield the block multiple times with different arguments:

subject.should_receive(:something).and_yield(item1).and_yield(item2)
Arne Hartherz
Last edit
Arne Hartherz
Keywords
call, invocation, returning, return
License
Source code in this card is licensed under the MIT License.
Posted by Arne Hartherz to makandra dev (2011-07-04 13:50)