有没有比 Rspec 的 `should_receive` 更具侵入性的替代方案? [英] Is there a less intrusive alternative to Rspec's `should_receive`?
问题描述
在编写 Rspec 测试时,我经常对 should_receive
感到沮丧.我想知道是否有其他侵入性较小的替代方案.
In writing Rspec tests, I'm often frustrated with should_receive
. I'd like to know if there's a less intrusive alternative.
例如:
describe "making a cake" do
it "should use some other methods" do
@baker.should_receive(:make_batter)
@baker.make_cake
end
end
对 should_receive
的调用是一个很好的描述,但它破坏了我的代码,因为 should_receive
通过屏蔽原始方法来工作,而 make_cake
除非 make_batter
实际返回一些面糊,否则无法继续.所以我把它改成这样:
The call to should_receive
is a good description, but it breaks my code, because should_receive
works by masking the original method, and make_cake
can't proceed unless make_batter
actually returns some batter. So I change it to this:
@baker.should_receive(:make_batter).and_return(@batter)
这很丑,因为:
- 看起来我正在测试
make_batter
是否正确返回@batter
,但我实际上强制make_batter
的假版本返回那个. - 它迫使我单独设置
@batter
- 如果
make_batter
有任何重要的副作用(我想这可能是代码异味),我也必须让它们发生.
- It looks like I'm testing that
make_batter
correctly returns@batter
, but I'm actually forcing the fake version ofmake_batter
to return that. - It forces me to separately set up
@batter
- If
make_batter
has any important side effects (which could be a code smell, I suppose) I have to make those happen, too.
我希望 should_receive(:make_batter)
能够验证方法调用并将其传递给原始方法.如果我想对它的行为进行存根以进行更好的隔离测试,我会明确地这样做:@baker.stub(:make_batter).and_return(@batter)
.
I wish that should_receive(:make_batter)
would verify the method call and pass it on to the original method. If I wanted to stub its behavior for better isolation testing, I would do so explicitly: @baker.stub(:make_batter).and_return(@batter)
.
有没有办法在不阻止原始方法调用的情况下执行类似 should_receive
的操作?我的问题是糟糕设计的征兆吗?
Is there a way to do something like should_receive
without preventing the original method call? Is my problem a symptom of bad design?
推荐答案
看起来更好的 API 委托给 Myron Marston 提到的原始方法实际上已经添加到 rspec-mocks v2.12.0
It looks like the nicer API to delegate to the original method that Myron Marston alluded to has actually been added in rspec-mocks v2.12.0
所以现在您可以在想要设置消息期望而不干扰对象如何响应消息"的任何时候简单地执行此操作:
So now you can simply do this any time you "want to set a message expecation without interfering with how the object responds to the message":
@baker.should_receive(:make_batter).and_call_original
感谢您添加此内容,迈伦.
Thanks for adding this, Myron.
这篇关于有没有比 Rspec 的 `should_receive` 更具侵入性的替代方案?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!