My program downloads a zip file from the web then parses it. The relevant parsing-related code is:
Zip::File.open("real_file.zip") do |zip_file|
# do stuff
end
In my RSpec test environment, I'd like to stub this code to parse a fake/mock file instead of the real one. Specifically, I'd like to replace the parameter value "real_file.zip" with "mock_file.zip".
I tried the following approach:
allow(Zip::File).to receive(:open).and_return(Zip::File.open("mock_file.zip"))
... but this prevents execution of code inside the block (# do stuff
). I don't want the mock file contents to be returned by the method, but rahter to be assigned to the value of zip_file
for further use. How can this be achieved?
Here's what you want to do:
What you're doing here is yielding a value to the block in your original code. The problem with simply returning a scalar value is that it doesn't yield anything to your block so it won't be called. Note that I'm opening the mock file before putting in the message expectation since it would also intercept your call to
Zip::File.open
and cause a nice stack overflow.More information: https://www.relishapp.com/rspec/rspec-mocks/v/3-2/docs/configuring-responses/block-implementation#yield-to-the-caller's-block