I'm having trouble figuring out how to stub only one of two calls to a method. Here's an example:
class Example
def self.foo
{ a: YAML.load_file('a.txt'), # don't stub - let it load
b: YAML.load_file('b.txt') } # stub this one
end
end
RSpec.describe Example do
describe '.foo' do
before do
allow(YAML).to receive(:load_file).with('b.txt').and_return('b_data')
end
it 'returns correct hash' do
expect(described_class.foo).to eq(a: 'a_data', b: 'b_data')
end
end
end
The test fails because I have stubbed a call to YAML.load_file
with the args for the second call ('b.txt'
), not the first one it encounters('a.txt'
). I thought argument matching would address this but it does not.
Failures:
1) Example.foo returns correct hash
Failure/Error:
{ a: YAML.load_file('a.txt'),
b: YAML.load_file('b.txt') }
Psych received :load_file with unexpected arguments
expected: ("b.txt")
got: ("a.txt")
Please stub a default value first if message might be received with other args as well.
Is there a way I can allow the first call to YAML.load_file
to go through but only stub the second call? How would I do this?
There is a and_call_original
option (see rspec docs).
Applied to your example, this should do what you are looking for:
before do
allow(YAML).to receive(:load_file).and_call_original
allow(YAML).to receive(:load_file).with('b.txt').and_return('b_data')
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With