RSpec:允许实例变量接收方法

时间:2016-07-01 22:44:50

标签: ruby rspec

说我有这个班:

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

当我在MyQueue实例上调用push时,如何测试实例变量@queue是否会收到push方法?

到目前为止我试过这个:

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

但是得到错误:

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

我做错了什么?

1 个答案:

答案 0 :(得分:2)

您正在创建MyQueue类的两倍,但未指定允许其接收#push,这就是my_queue.push(message_line)行失败的原因。

事实上,你的方向是错误的。您想要测试使用MyQueue实例的Queue类的方法。你想要做的是将与Queue交互相关的所有内容存根,但你改为模拟MyQueue实例(my_queue)使其成为虚拟(所以,对它进行所有调用,包括你要测试的#push,虚拟)。

以下是我认为应该如何测试:

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