2

My spec_helper.rb has the following configuration:

RSpec.configure do |config|
    config.mock_with :mocha
    # .. other configs
end

I want to test the following piece of code:

File.open('filename.zip', 'wb') do |file|
    file.write('some file content')
end

So here is my spec:

file_handle = mock
file_handle.stubs(:write).with('some file content').once
File.stubs(:open).with('filename.zip', 'wb').returns(file_handle).once

But the output says there is no invocation of write method.

Here is the output:

MiniTest::Assertion: not all expectations were satisfied
unsatisfied expectations:
- expected exactly once, not yet invoked: #<Mock:0x7fdcdde109a8>.write('some file content')
satisfied expectations:
- expected exactly once, invoked once: File.open('filename.zip', 'wb')

So am I stubbing the write method in the right way? If not, is there any other way to write spec for method invocation inside do |obj| ..end block?

Vega
  • 27,856
  • 27
  • 95
  • 103
arunvelsriram
  • 1,036
  • 8
  • 18

2 Answers2

2

You can simply write:

file_handle = mock
file_handle.stubs(:write).with('some file content').once
File.stubs(:open).with('filename.zip', 'wb').yields(file_handle).once
Sergei Stralenia
  • 855
  • 7
  • 16
-1

Not sure it is your case but I think it can help you

I needed to change behavior inside block File.open(...) do ... end

I managed to do it this way

origin_open = File.method(:open)
allow(File).to receive(:open) do |*args, &block|
  if condition
    # change behavior here
    # for example change args
  end
  # call original method with modified args
  origin_open.call(*args, &block)
end

This article helped me a lot

gotva
  • 5,919
  • 2
  • 25
  • 35