Read more

RSpec: Stubbing a method that takes a block

Arne Hartherz
July 04, 2011Software engineer at makandra GmbH

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.

Illustration book lover

Growing Rails Applications in Practice

Check out our e-book. Learn to structure large Ruby on Rails codebases with the tools you already know and love.

  • Introduce design conventions for controllers and user-facing models
  • Create a system for growth
  • Build applications to last
Read more Show archive.org snapshot

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)
Posted by Arne Hartherz to makandra dev (2011-07-04 15:50)