Ruby on rails Rspec:如何期望收到的消息不会在幕后留下任何痕迹或更改任何内容

Ruby on rails Rspec:如何期望收到的消息不会在幕后留下任何痕迹或更改任何内容,ruby-on-rails,rspec,rspec-rails,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(

我对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,在这个类方法中,我想确保类的某个成员也在接收其他消息。我不想删除那些方法,我想让它们正常运行,但我只想验证这些方法是否正在被调用

这是在一个循环中运行的,所以我不知道具体要处理哪些实例,但我想确保在某些成员上调用这两条消息,但不一定是在一个类的两次调用同一个成员,总共两次

如果我删除expect\u any\u instance\u of a.to receive expections,那么一切运行正常,测试通过

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

我试着添加和调用原创,但我觉得我是在黑暗中拍摄,因为文档不清楚这些方法实际上是如何操作的

那么,如何验证某个类的实例在不改变方法调用的任何其他内容的情况下接收了n次消息呢


我是否错过了期待在这里收到的要点?我不清楚为什么它首先会存根任何东西。

我知道这并不能准确回答您关于如何继续执行的问题,但您应该能够将此测试分为三个不同的测试,并创建一组更清晰的测试,同时不必担心调用原始测试:

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

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

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

您可以监视以下方法:

allow(A).to receive(:calculate_volume).and_call_original
expect(A).to have_received(:calculate_volume)
然后您可以测试calculate_volume的调用方式如下:

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

通过这种方式,将调用原始方法,而不是存根,而是进行监视。

您可以像这样监视该方法:

allow(A).to receive(:calculate_volume).and_call_original
expect(A).to have_received(:calculate_volume)
然后您可以测试calculate_volume的调用方式如下:

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

这样就可以调用原始方法,而不是存根,而是监视。

你说文档不清楚和调用原始方法是什么意思。它们非常简单,就像方法本身的名称一样。你说文档不清楚,称之为原创是什么意思。它们非常简单,就像方法本身的名称一样。