如何使用 rspec/rspec-mocks 存根 class 方法

How to stub a class method using rspec/rspec-mocks

我正在使用 rspec-mock 进行测试驱动开发。 我开始使用 rspec-mock 实现一个 class 和 mocking/stubbing 其他 classes。 classes 尚未实现的模拟对象运行良好。 但是,当我尝试模拟尚不存在的 class 的 class 方法时,我没有成功。 我的 class "Hashes" 应该有一个 class 方法 "calculate_hashes" 接收文件名并返回哈希值。

我试过了

 allow(Hashes).to receive(:calculate_hash) do |file| 
      # looks up what to return
 end

给出错误 "Hashes is not a class"。 然后我实现了一个 class "Hashes"

class Hashes
end

然后只尝试以相同的方式对 class 方法进行存根。 这给出了错误 "Hashes does not implement: calculate_hash" 然后,当我将该方法添加到我的 class 定义中时:

class Hashes
    def self.calculate_hash(filename)
    end
end

它终于起作用了,我对这个 class 方法的存根使用 "allow(Hashes)" 起作用,如上例所示。 我只是想知道是否有一种方法可以在不编写此 class 框架的情况下完成此操作。

或者我可能试图以不恰当的方式完成某些事情? 或者 rspec-mock 可能不是执行此操作的正确工具?

非常感谢任何帮助。

对于您的工作流程,我认为使用 class_double 比直接存根 Hashes class 效果更好。 allow(Hashes) 总是 要求定义 Hashes 常量。这就是 Ruby 的工作原理,而 RSpec 对此无能为力。使用 class double,您可以改为这样做:

class_double("Hashes", :calculate_hash => canned_return_value).as_stubbed_const

# or

hashes = class_double("Hashes").as_stubbed_const
allow(hashes).to receive(:calculate_hash) do |file|
  # look up what to return
end

class_double("Hashes") 为您提供了一个测试替身,当定义了 Hashes 常量时,它将根据 Hashes class 定义验证模拟和存根方法,但是当它没有被定义时,它就像一个普通的替身一样,允许任何东西被嘲笑或存根。 as_stubbed_const 位告诉 rspec-mocks 在示例期间存根 Hashes 常量,以便对 Hashes 的任何引用都使您的 class 加倍而不是真正的 Hashes class,即使 Hashes class 从未被定义过。