I have a Ruby cli program that can optionally load a user-specified file via require. I would like to unit test this functionality via RSpec. The obvious thing to do is to mock the require and verify that it happened. Something like this:
context 'with the --require option' do
let(:file) { "test_require.rb" }
let(:args) { ["--require", "#{file}"] }
it "loads the specified file"
expect(...something...).to receive(:require).with(file).and_return(true)
command.start(args)
end
end
(That's just typed, not copy/pasted - the actual code would obscure the question.)
No matter what I try, I can't capture the require, even though it's occurring (it raises a LoadError, so I can see that). I've tried a variety of things, including the most obvious:
expect(Kernel).to receive(:require).with(file).and_return(true)
or even:
let(:kernel_class) { class_double('Kernel') }
kernel_class.as_stubbed_const
allow(Kernel).to receive(:require).and_call_original
allow(Kernel).to receive(:require).with(file).and_return(true)
but nothing seems to hook onto the require
Suggestions?
So
requireis defined byKernelbutKernelis included inObjectso when you callrequireinside this context it is not necessarily theKernelmodule that is processing the statement.Update
I am not sure if this exactly solves your issue but it does not suffer from the strange behavior exhibited below:
Working Example
OLD Answer:
This is incorrect and exists only for posterity due to the up-votes received. Some how works without the
allow. Would love it if someone could explain why as I assumed it should raise instead. I believe the issue to be related toand_returnwhere this is not part of the expectation. My guess is we are only testing that self receivedrequire,with_file, and that theand_returnportion is just a message transmission (thus my updated answer)You can still stub this like so:
Since I am unclear on your exact implementation since you have obfuscated it for the question I cannot solve your exact issue.