Object.any_instance should_receive vs expect()接收

Cal*_*lin 75 rspec rspec2 rspec-rails

以下代码按预期工作:

Object.any_instance.should_receive(:subscribe)
Run Code Online (Sandbox Code Playgroud)

但是当使用新的rspec期望时,它不起作用:

expect(Object.any_instance).to receive(:subscribe)
Run Code Online (Sandbox Code Playgroud)

错误是:

expected: 1 time with any arguments
received: 0 times with any arguments
Run Code Online (Sandbox Code Playgroud)

如何使expect()接收?

Pet*_*vin 152

现在有一个没有很好记录的方法expect_any_instance_of来处理any_instance特殊情况.你应该使用:

expect_any_instance_of(Object).to receive(:subscribe)
Run Code Online (Sandbox Code Playgroud)

谷歌expect_any_instance_of了解更多信息.

  • @rubyprince它们是不同的,允许方法存根行为和期望方法测试行为。例如,“allow(my_obj).to receive(:method_name).and_return(true)”存根“my_obj.method_name()”,因此如果在测试中调用它,它只会返回“true”。`expect(my_obj).to receive(:method_name).and_return(true)` 不会改变任何行为,但如果稍后在测试中未调用 `my_obj.method_name()` 则设置测试期望失败,或者不返回 true。 (2认同)
  • 不推荐使用此语法.在今天的语法中有没有关于如何做到这一点的提示? (2认同)

Arr*_*eth 9

expect_any_instance_of根据Jon Rowe(rspec 关键贡献者)的说法,现在被认为是已弃用的行为,请注意。建议的替代方法是使用该instance_double方法创建类的模拟实例,并期望对该实例进行双重调用,如该链接中所述。

Jon 的方法是首选(因为它可以用作通用测试辅助方法)。但是,如果您发现这令人困惑,希望您的示例案例的实现可以帮助理解预期的方法:

mock_object = instance_double(Object) # create mock instance
allow(MyModule::MyClass).to receive(:new).and_return(mock_object) # always return this mock instance when constructor is invoked

expect(mock_object).to receive(:subscribe)
Run Code Online (Sandbox Code Playgroud)

祝你好运!