Misha Slyusarev
Misha Slyusarev

Reputation: 1383

RSpec: Allow instance variable to receive method

Say I have this class:

class MyQueue
  def initialize
    @queue = Queue.new
  end
  def push(line)
    @queue.push(line)
  end
end

How should I test that instance variable @queue will receive push method when I call for push on MyQueue instance?

I tried this so far:

describe MyQueue do
  let(:my_queue) { instance_double('MyQueue') }
  let(:message_line) { double('message_line') }

  describe '#push' do
    before do
       instance_queue = my_queue.instance_variable_set(:@queue, double)
       allow(instance_queue).to receive(:push) { message_line }
    end

    it 'adds line to the queue' do
      expect(my_queue.instance_variable_get(:@queue)).to receive(:push) { message_line }
      my_queue.push(message_line)
    end
  end
end

But getting error:

#<InstanceDouble(MyQueue) (anonymous)> received unexpected message :push 
with (#<Double "message_line">)

What am I doing wrong?

Upvotes: 2

Views: 5812

Answers (1)

Rustam Gasanov
Rustam Gasanov

Reputation: 15781

You are creating double of MyQueue class but you do not specify that it is allowed to receive #push, that's why it fails on my_queue.push(message_line) line.

In fact, you are going in wrong direction. You want to test a method of the MyQueue class, which uses Queue instance. What you want to do is to stub everything related to the interaction with Queue, but you instead mock MyQueue instance(my_queue) making it dummy(and so, making all calls to it, including #push, which you want to test, dummy).

Here is how I see it should be tested:

describe MyQueue do
  let(:queue) { instance_double('Queue') }
  let(:message_line) { double('message_line') }

  describe '#push' do
    before do
      allow(Queue).to receive(:new).and_return(queue)
      allow(queue).to receive(:push).with(message_line)
    end

    it 'adds line to the queue' do
      expect(queue).to receive(:push).with(message_line)
      MyQueue.new.push(message_line)
    end
  end
end

Finished in 0.00575 seconds (files took 0.27625 seconds to load)
1 example, 0 failures

Upvotes: 4

Related Questions