Mocking a libraries loop method

In the following test I’m trying to stub out the loop method of the Kafka consumer and then use spies to make sure an activity is created:

describe MessageImporter, '#start' do
  it 'creates an activity' do
    activity = double(create: true)
    consumer = double(loop: [:message])

    MessageImporter.new(consumer, activity).start

    expect(activity).to have_received(:create).with(:message)
  end
end

The MessageImporter class looks like this:

class MessageImporter
  attr_reader :activity, :consumer

  def initialize(consumer, activity)
    @activity = activity
    @consumer = consumer
  end

  def start
    consumer.loop do |messages|
      messages.each do |message|
        activity.create(message)
        consumer.increment_offset
      end
    end
  end
end

The problem is I can’t get the loop block to execute. Any ideas?

Looks like you’ve defined loop to just be a method on consumer that returns [:message], but you haven’t told it what to do when you pass it a block.

So, I suspect you’re getting a return value of [:message], but it’s discarding the block.

I think Ben’s right.

consumer = double("Consumer")
consumer.stub(:loop).and_yield([:message])

Should work.

2 Likes

Nice Pat. That did the trick! Thanks.