对于Rspec的“should_receive”,是否有一个较less侵入的select?
在编写Rspectesting时,我经常为should_receive
感到沮丧。 我想知道是否有一个不太干扰的select。
例如:
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
实际返回一些连击。 所以我改变它:
@baker.should_receive(:make_batter).and_return(@batter)
这是丑陋的,因为:
- 它看起来像我testing
make_batter
正确地返回@batter
,但我实际上是迫使伪造的版本make_batter
返回。 - 它迫使我分别设置
@batter
- 如果
make_batter
有任何重要的副作用(这可能是一种代码味道,我想),我也必须做到这一点。
我希望should_receive(:make_batter)
将validation方法调用并将其传递给原始方法 。 如果我想将它的行为存储为更好的隔离性testing,我会明确地这样做: @baker.stub(:make_batter).and_return(@batter)
。
有没有办法做一些像should_receive
而不阻止原始方法调用? 我的问题是不良devise的症状吗?
它看起来像更好的API委托给原来的方法,Myron马斯顿暗示实际上已经添加在rspec-mocks v2.12.0
- 添加
and_call_original
代表原来的方法。
所以,现在只要你“想要设置一个消息预览而不会干扰对象如何响应消息”,你就可以简单地做到这一点:
@baker.should_receive(:make_batter).and_call_original
谢谢你,Myron。
你可以让should_receive
像这样运行原始的方法:
@baker.should_receive(:make_batter, &@baker.method(:make_batter))
这两个should_receive
和stub
支持通过一个块实现(当方法被调用时被eval'd)。 &@baker.method(:make_batter)
获取原始方法对象的句柄,并将其作为块实现传递。
FWIW,我们想提供一个更好的API委托给原来的方法(见这个问题 ),但是很难在不破坏向后兼容性的情况下添加这个function。
你有这个问题,因为你正在testingmake_cake
方法的实现细节。 在编写testing时,应该只关注行为,而不是内部方法调用的序列。 否则,以后重构你的代码会导致所有testing的巨大重构。
当你想单独testing你的课程时,Mock和Stubs派上用场。 在编写unit testing时,应将testing对象与其他对象隔离。 当你一次处理多个对象时,两者都起到了替身的作用。 在这种情况下,您可以使用should_receive
来确保您的testing主题通过调用方法正确地将某个任务委托给另一个对象。