Stubbing out class method using Mocha

2019-07-23 04:44发布

问题:

I have a method I want to test using rspec and Mocha. My aim is to stub out Dir.glob in order to just return a simple array of one file. The method is defined as so:

def my_method
  Dir.glob("#{upload_dir}/*.pdf").each do |file|
    ...
  end
end

And the test:

it "ignores a file of no size" do
  zero_file = File.expand_path("../fixtures/zero_size_file_12345.pdf", __FILE__)
  Dir.expects(:glob).returns([zero_file])

  ...
end

The problem is that the method upload_dir is not something I want to test here, and I assumed if I stubbed out any call to Dir.glob then upload_dir would never be called. If I put a debugger in before the call to Dir.glob and call Dir.glob, then I see my array of one zero file, so the stubbing is definitely working. However, when the test actually calls the method Dir.glob("#{upload_dir}/*.pdf"), it's trying to then call upload_dir.

I'm using Ruby 1.9.3, rspec 2.12.0 and mocha 0.13.0.

回答1:

Its calling upload_dir because it has to to build the string to pass to glob. You could stub it by adding something like -

[YourClass].expects(:upload_dir).returns("foo")

and then expect that your code passes "foo/*.pdf" to glob.



回答2:

What @Scott suggests would probably work. So +1 for his answer.

However, you should think about extracting out the line:

Dir.glob("#{upload_dir}/*.pdf")

into a method that clarifies intent,for e.g. pdf_files_to_upload.

You could then stub out that method on the object under test to return an array as required. You are then decoupled from the upload_dir method entirely and don't need to care how the list of PDF files is generated. A more declarative my_method would result!

HTH.



标签: ruby rspec mocha