Rspec:如何期待收到的消息而不会在后台进行任何存根或更改任何内容

时间:2018-06-19 17:22:44

标签: ruby-on-rails rspec rspec-rails

我有针对Rails应用的Rspec测试

  describe '.move_probes_to_master_list' do
    let(:as) { create_list :a, 3, }
    let(:bs) { create_list :b, 3 }

    it 'sums the volumes' do

      active_as= [as[1], as[2]]
      b_ids = [2, 3]
      expect_any_instance_of(A)
        .to receive(:required_volume).twice.with(b_ids)
      expect_any_instance_of(A)
        .to receive(:update_move_to_master_list).twice

      expect(A.calculate_volume(active_as)).to eq(true)
    end
  end

基本上,我调用A.calculate_volume,并且在此类方法中,我想确保A类的某些成员也接收到其他消息。我不想存根那些方法,我希望它们正常运行,但我只想验证这些方法是否正在被调用。

这是循环运行的,所以我不知道我将要处理的是什么实例,但是我想确保两个消息都在某些成员上被调用(但不一定两次都在同一成员上) )总共A类的

如果我取消了expect_any_instance_of(A).to receive的期望,那么一切都会顺利进行,并且测试会通过。

如果我保留它们,方法调用将失败并且测试将中断。

我尝试添加and_call_original,但是我觉得我在黑暗中射击,因为文档尚不清楚这些方法的实际操作方式。

那么我如何验证某个类的实例收到n次消息,而没有更改方法调用的其他内容?

我想错过在这里收到的礼物吗?对我来说,尚不清楚为什么它会一开始就存根任何东西。

2 个答案:

答案 0 :(得分:2)

您可以监视这种方法:

allow(A).to receive(:calculate_volume).and_call_original

然后,您可以测试calculate_volume是否已被这样调用:

expect(A).to have_received(:calculate_volume)

这样,将调用原始方法,并且不会进行任何侦查,而是进行间谍监视。

答案 1 :(得分:-1)

我知道这并不能完全回答您的问题“如何继续执行”,但是您应该能够将此测试分为三个不同的测试并创建更清晰的测试集,而不必担心调用原始测试这样:

describe '.move_probes_to_master_list' do
  let(:as) { create_list :a, 3, }
  let(:active_as) { [as[1], as[2]] }
  let(:bs) { create_list :b, 3 }
  let(:b_ids) { [2, 3] }
  subject { A.calculate_volume(active_as) }

  it 'sums the volumes' do
      expect(subject).to eq(true)
  end

  it 'calls #required_volumen twice' do
    expect_any_instance_of(A)
      .to receive(:required_volume).twice.with(b_ids)
    subject
  end

  it 'calls updates_moves_to_master_list twice' do
    expect_any_instance_of(A)
      .to receive(:update_move_to_master_list).twice
    subject
  end
end