Posted over 8 years ago. Visible to the public.

RSpec: Stubbing a method that takes a block

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:

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

It works similar to and_return – just use and_yield:

Copy
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:

Copy
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:

Copy
subject.should_receive(:something).and_yield(item1).and_yield(item2)

By refactoring problematic code and creating automated tests, makandra can vastly improve the maintainability of your Rails application.

Owner of this card:

Avatar
Arne Hartherz
Last edit:
over 2 years ago
by Arne Hartherz
Keywords:
call, invocation, returning, return
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Arne Hartherz to makandra dev
This website uses cookies to improve usability and analyze traffic.
Accept or learn more