【问题标题】:Observing strange behavior with `allow` and `have_received` with rspec用 rspec 观察 `allow` 和 `have_received` 的奇怪行为
【发布时间】:2020-05-14 05:11:08
【问题描述】:

我在规范中使用 allow 和 have_received 时遇到问题

我有一个名为Obj 的模型,它与一个名为Parent 的模型有belongs_to 关系。 Parent 模型与 Obj 具有 has_many 关系。

在Obj 模型中,我定义了一个名为child_method 的方法。在Parent 模型中,我定义了一个名为calls_child_method 的方法,它遍历与之关联的每个Obj,并让它们调用child_method

我正在编写一个规范来测试这种行为,如下所示,但它一直失败:

describe 'parent calls_child_method' do
  let(:obj) { Obj.create }

  before do
    allow(obj).to receive(:child_method)
  end

  it 'should call child_method' do
    obj.parent.calls_child_method
    expect(obj).to have_received(:child_method)
  end
end

输出:

expected: 1 time with any arguments
received: 0 times with any arguments

但是,当我使用allow_any_instance_of 进行间谍/存根时,这似乎通过了:

describe 'parent calls_child_method' do
  let(:obj) { Obj.create }

  before do
    allow(obj).to receive(:child_method)
  end

  it 'should call child_method' do
    expect_any_instance_of(Obj).to receive(:child_method)
    obj.parent.calls_child_method
  end
end

或者如果我直接调用子方法:

describe 'parent calls_child_method' do
  let(:obj) { Obj.create }

  before do
    allow(obj).to receive(:child_method)
  end

  it 'should call child_method' do
    obj.child_method
    expect(obj).to have_received(:child_method)
  end
end

在所有这一切中,我已经通过使用byebug 调试来验证创建的Obj 实例实际上是在调用child_method,以查看它正在被调用。

有人能帮我理解为什么规范/间谍会这样吗?

【问题讨论】:

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


    【解决方案1】:

    这个问题困扰了我很多年。这就是我理解正在发生的事情的方式。

    在您失败的情况下,obj 是对您新创建的Obj.create 的引用。通过调用expect(obj).to have_received(:child_method),预计精确引用obj 应该收到child_method。

    当obj 的父级收到calls_child_method 时,它会遍历与其关联的每个 Obj。很可能它会调用parent.objs,这将触发一个新的数据库调用。在您的情况下,它将找到您的obj,但会有不同的引用。而那个不同的参考将是得到child_method

    这就是为什么从技术上讲,您的对象确实会收到方法调用,但通过不同的引用。结果你的期望失败了:(

    expect_any_instance_of(Obj) 解决了这个问题。但是,通常最好避免它。

    您的最后一个示例是成功的,因为您的期望和方法调用使用相同的对象/引用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-02
      • 1970-01-01
      • 1970-01-01
      • 2020-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多