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

我正在使用rspec-mock进行测试驱动开发。 我开始实现一个单独的类,并使用rspec-mock来模拟/存根其他类。 模拟尚未实现的类的对象效果很好。 但是,当我尝试模拟一个尚不存在的类的类方法时,我还没有成功。 我的类“Hashes”应该有一个类方法“calculate_hashes”接收文件名并返回一个哈希值。

我试过了

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

给出错误“哈希不是一个类”。 然后我实施了一个类“哈希”

 class Hashes end 

然后只尝试以相同的方式存根类方法。 这给出了错误“Hashes没有实现:calculate_hash”当我然后将方法添加到我的类定义时:

 class Hashes def self.calculate_hash(filename) end end 

它最终工作,我的这个类方法的存根使用“allow(Hashes)”工作,如上例所示。 我只是想知道是否有一种方法可以在不编写此类骨架的情况下完成此操作。

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

任何帮助是极大的赞赏。

对于您的工作流程,我认为使用class_double比直接存根class_double类更好。 allow(Hashes) 总是要求定义Hashes常量。 它只是Ruby的工作方式,而RSpec对此无能为力。 使用类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")为您提供了一个测试double,当定义Hashes常量时,将validation针对Hashes类定义的Hashes和存根方法,但是当它未定义时,将像普通的double一样使用任何被嘲笑或抄袭的东西。 as_stubbed_const位告诉rspec-mocks在示例的持续时间as_stubbed_const常量,这样对Hashes任何引用都会使你的类变为double而不是真正的Hashes类,即使从未定义过Hashes类。