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

Jue*_*gen 5 ruby rspec mocking rspec-mocks

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

我试过了

 allow(Hashes).to receive(:calculate_hash) do |file| 
      # looks up what to return
 end
Run Code Online (Sandbox Code Playgroud)

这给出了错误"哈希不是一个类".然后我实施了一个类"哈希"

class Hashes
end
Run Code Online (Sandbox Code Playgroud)

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

class Hashes
    def self.calculate_hash(filename)
    end
end
Run Code Online (Sandbox Code Playgroud)

它最终工作,我的这个类方法的存根使用"allow(Hashes)"工作,如上例所示.我只是想知道是否有办法在不编写这个类骨架的情况下完成这个.

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

任何帮助是极大的赞赏.

Myr*_*ton 10

对于您的工作流程,我认为使用A class_double而不是Hashes直接存根该类会更好. 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
Run Code Online (Sandbox Code Playgroud)

class_double("Hashes")为你提供了一个测试双精度,当定义Hashes常量时,将根据Hashes类定义验证模拟和存根方法,但是当它没有被定义时,它将像普通双重一样,允许任何东西被模拟或存在于其上.该as_stubbed_const位告诉rspec-mocks Hashes在示例的持续时间内对常量进行存根,以便任何引用都可以Hashes使您的类加倍而不是真正的Hashes类,即使Hashes该类从未被定义过.