Rspec - 结合expect_any_instance_of和接收计数

时间:2016-02-10 16:59:45

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

我需要验证我的类的任何实例都接收某种方法,但我不关心是否有很多实例接收它(它们应该是)。

我试过这样:

expect_any_instance_of(MyClass).to receive(:my_method).at_least(:once)

但显然,它只允许单个实例多次接收该方法,但不适用于不同的实例。

有没有办法实现这个目标?

2 个答案:

答案 0 :(得分:7)

这是rspec-mocks中的一个已知问题。来自Any instance上的v3.4 documentation

  

rspec-mocks API是为单个对象实例设计的,但此功能适用于整个对象类。结果,存在一些语义上令人困惑的边缘情况。例如,在expect_any_instance_of(Widget).to receive(:name).twice中,不清楚特定实例是否应该接收两次名称,或者是否预期两次接收总数。 (它是前者。)

此外

  

使用此功能通常是一种设计气味。可能是您的测试试图做得太多或者被测对象太复杂了。

你有没有办法重构你的测试或应用程序代码,以避免混淆边缘情况"?也许通过构建一个测试double并期望它接收消息?

答案 1 :(得分:6)

如果你需要忍受代码气味,this rspec-mocks Github issue建议解决这些问题:

receive_count = 0
allow_any_instance_of(MyClass).to receive(:my_method) { receive_count += 1 }

# Code to test here.

expect(receive_count).to be > 0