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

时间:2015-06-15 15:18:47

标签: ruby rspec mocking rspec-mocks

I am using rspec-mock for test-driven-development. I am starting implementing a single class and mocking/stubbing the other classes using rspec-mock. Mocking objects of classes yet to be implemented works well. However when I try to mock a class method of a class that does not exist yet, I haven't been successful. My class "Hashes" should have a class method "calculate_hashes" receiving a filename and returning a hash.

I tried

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

which give the error "Hashes is not a class". I then implemented a class "Hashes"

class Hashes
end

and then only tried to stub the class method in the same way. This gives the error "Hashes does not implement: calculate_hash" When I then add the method to my class definition:

class Hashes
    def self.calculate_hash(filename)
    end
end

it finally works and my stubbing of this class method works using "allow(Hashes)" as seen in the example above. I just wonder if there is a way of accomplishing this without writing this class skeleton.

Or am I maybe trying to accomplish something in an inappropriate way? Or is rspec-mock maybe not the right tool to do this?

Any help is greatly appreciated.

1 个答案:

答案 0 :(得分:10)

对于您的工作流程,我认为使用if regex =~ url != nil then # returns nil if no match else returns index of first character matched 而不是直接存根class_double类会更好。 Hashes 总是要求定义allow(Hashes)常量。它只是Ruby的工作方式,而RSpec对此无能为力。使用class double,您可以执行此操作:

Hashes

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位告诉rspec-mocks在示例的持续时间内存根as_stubbed_const常量,以便对Hashes的任何引用使您的类加倍而不是真正的Hashes类,即使从未定义过Hashes类。