如何期望在Rails中使用某些参数将消息发送到任何类的实例(总共两次)?

时间:2017-04-13 15:06:10

标签: ruby-on-rails rspec

退款时,我们需要停用附有该订单的连续出版物。在规范中,订单有两个连续出版物,我必须要求对API进行两次调用,以便停用连续出版物。

我试过了:

expect_any_instance_of(Gateway).to receive(:deactivate_dongle).once.with(serial_number: '67890')
expect_any_instance_of(Gateway).to receive(:deactivate_dongle).once.with(serial_number: '12345')

这给了我:

The message 'deactivate_dongle' was received by #<Gateway:70179265658480 @connection=#<Faraday::Connection:0x007fa7c4667b28>> but has already been received by #<Gateway:0x007fa7c6858160>

同样的:

expect_any_instance_of(Gateway).to receive(:deactivate_dongle).with(serial_number: '12345')
expect_any_instance_of(Gateway).to receive(:deactivate_dongle).with(serial_number: '67890')

我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:3)

如果您可以更改实施以针对已知的Gateway实例提出预期(为了避免expect_any_instance_of),您可以使用rspec的ordered方法添加接收限制消息。

我担心在你的情况下你应该尝试添加一个规范,其中只涉及其中一个系列,所以你可以正确地期望它。 e.g。

expect_any_instance_of(Gateway).to receive(:deactivate_dongle).once.with(serial_number: '67890')

然后有一个带有n个连续剧的规范,只希望deactivate_dongle被调用n次。

答案 1 :(得分:1)

我认为你需要一个Null Object

  

使用as_null_object方法忽略任何不明确的消息   设置为存根或消息期望。

allow_any_instance_of(JarvisGateway).to receive(:deactivate_dongle).as_null_object


这是我在找到上述解决方案之前想到的另一个解决方案。与内置匹配器相比,Blocks在检查args方面提供了更大的灵活性。请参阅Use a block to verify arguments

allow_any_instance_of(JarvisGateway).to receive(:deactivate_dongle) do |args|
  expect(['67890', '12345']).to include args[:serial_number]
end

expect_any_instance_of(JarvisGateway).to receive(:deactivate_dongle).twice


不确定allow_any_instance_of是否支持这种阻止 如果它没有,那么您可以通过以下一项或多项来完成:

  1. 创建JarvisGateway的实例并检查发送给的消息 而不是allow_any_instance_of
  2. 使用has_received代替to receive。见Spies

  3. 编辑: 实际上expect_any_instance_of(JarvisGateway).to receive(:deactivate_dongle).twice并不是很好,因为它没有检查每个序列号是否被调用一次。