在写Rspec测试时,我经常对should_receive个测试感到沮丧.我想知道是否有一个不那么麻烦的替代方案.

例如:

describe "making a cake" do
  it "should use some other methods" do
    @baker.should_receive(:make_batter)
    @baker.make_cake
  end
end

should_receive的调用是一个很好的描述,但它 destruct 了我的代码,因为should_receive通过屏蔽原始方法工作,而make_cake不能继续,除非make_batter实际返回一些batter.所以我把它改成:

@baker.should_receive(:make_batter).and_return(@batter)

这很难看,因为:

  • 这就像我在测试make_batter正确返回@batter,但我是actually强迫make_batter的假版本返回它.
  • 它迫使我单独设置@batter
  • 如果make_batter有任何重要的副作用(我想可能是代码气味),我也必须让它们发生.

我希望should_receive(:make_batter)验证方法调用,pass it on to the original method验证方法调用.如果我想存根它的行为以进行更好的隔离测试,我会明确地这样做:@baker.stub(:make_batter).and_return(@batter).

有没有一种方法可以在不阻止原始方法调用的情况下执行类似于should_receive的操作?我的问题是设计不好的症状吗?

推荐答案

Myron Marston提到的原始方法的委托似乎比rspec-mocks v2.12.0年前添加的API更好

因此,现在您可以在任何时候简单地执行此操作,您"想要设置消息expecation而不干扰对象对消息的响应":

@baker.should_receive(:make_batter).and_call_original

谢谢你加上这个,迈伦.

Ruby相关问答推荐

Rb:仅通过在 Ruby 中的类上添加 each 方法,可枚举模块是如何工作的?

while 语句的主体是块吗?

使用 Drive API 创建空文件

Ruby 符号到类

如何在 Ruby 中合并多个哈希?

如何打开(读写)或创建允许截断的文件?

define_method:如何动态创建带参数的方法

何时在 Ruby 方法中使用 `self.foo` 而不是 `foo`

Sublime Text 2 中的 RubyTest

复制文件,在 Ruby 中根据需要创建目录

Rails - RSpec - let和let!之间的区别

在包含任意数量的嵌套散列和数组的散列中查找键/值对

如何声明 RSpec 中示例之间共享的变量?

如何自定义 Jekyll 的 url?

Ruby Koan 151 引发异常

理解 Ruby 中的私有方法

如何在 Ruby 中重命名文件?

Ruby 疯狂:类与对象?

如何在 gemspec 中指定最低 Ruby 版本?

如何创建一个 Gemfile?