How do I stub a file.read call so that it returns what I want it to? The following does not work:
def write_something
File.open('file.txt') do |f|
return contents = f.read
end
end
# rspec
describe 'stub .read' do
it 'should work' do
File.stub(:read) { 'stubbed read' }
write_something.should == 'stubbed read'
end
end
It looks like the stub is being applied to the File class and not the file instance inside my block. So File.read returns stubbed read as expected. But when I run my spec it fails.
I should note that
File.openis just one part of Ruby’s very large I/O API, and so your test is likely to be very strongly coupled to your implementation, and unlikely to survive much refactoring. Further, one must be careful with “global” mocking (i.e. of a constant or all instances) as it can unintentionally mock usages elsewhere, causing confusing errors and failures.Instead of mocking, consider either creating an actual file on disk (using
Tempfile) or using a broader I/O mocking library (e.g. FakeFS).If you still wish to use mocking you can somewhat safely stub
File.opento yield a double (and only when called with the correct argument):or, somewhat dangerously, stub all instances: