I want to test the else
branch of the following ruby code:
SCHEMA_SOURCE = if File.exist? SCHEMA_FILENAME
SCHEMA_FILENAME
else
ContentfulApi::Http
end
I cannot find a way to mock the non-existence of the file SCHEMA_FILENAME
. Here are the simplified versions of the test I have tried, and the error:
it 'fails to find file when it does not exist' do
allow(File).to receive(:exists?).and_return(false)
expect(File.exist?(ContentfulApi::SCHEMA_FILENAME)).to be_falsey
end
it 'fails to find file when it does not exist' do
allow(File).to receive(:exists?).with(ContentfulApi::SCHEMA_FILENAME)\
.and_return(false)
expect(File.exist?(ContentfulApi::SCHEMA_FILENAME)).to be_falsey
end
These both fail with the error
expected: falsey value
got: true
it 'fails to find file when it does not exist' do
File.stub(:exists?) { false }
expect(File.exist?(ContentfulApi::SCHEMA_FILENAME)).to be_falsey
end
it 'fails to find file when it does not exist' do
File.stub!(:exists?).with(ContentfulApi::SCHEMA_FILENAME)\
.and_return(false)
expect(File.exist?(ContentfulApi::SCHEMA_FILENAME)).to be_falsey
end
These both fail with the error
undefined method `stub' for File:Class
My first two attempts follow the example in the Method Stubs documentation, though there may be a distinction between classes and objects that is not explored in that documentation. (Though classes are objects in Ruby, right?)
The second two attempts follow older documentation.
How should I stub File.exist? SCHEMA_FILENAME
so that it returns false
even though the file does actually exist?
N.B. The approaches in these similar questions do not work:
- rspec to stub several File.exists? calls
- Rspec -- need to stub File.open that gets called in another file
- rspec undefined method stub for model
- how to reset expectations on a mocked class method?
- How do I stub out a specific file with rspec?
- Can't stub things with Rspec
- rspec 3 - stub a class method
CodePudding user response:
You're mocking File.exists?
and calling File.exist?
.
Note that if you have verify_partial_doubles
set, and you should, RSpec won't allow you to mock a method which does not exist.
RSpec.configure do |config|
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
end
RSpec.describe File do
it 'cannot mock a method whcih does not exist' do
allow(File).to receive(:dslkfjalk).and_return(true)
end
end
Failures:
1) File cannot mock a method whcih does not exist
Failure/Error: allow(File).to receive(:dslkfjalk).and_return(true)
File does not implement: dslkfjalk
But File
does have both exist?
and exists?
methods. File.exists?
is deprecated and removed from the documentation, but I guess it still... exists.