我有一个Ruby cli程序,可以选择通过require
加载用户指定的文件。我想通过RSpec对该功能进行单元测试。显而易见的事情是模拟需求并验证它是否已发生。像这样:
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
(只是输入,而不是复制/粘贴-实际的代码会使问题难以理解。)
无论我尝试什么,即使发生require
,我也无法捕获它(它会引发LoadError
,因此我可以看到它)。我尝试了各种方法,包括最明显的方法:
expect(Kernel).to receive(:require).with(file).and_return(true)
甚至:
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)
但似乎没有任何东西挂在require
建议?
答案 0 :(得分:6)
因此require
由Kernel
定义,但是Kernel
包含在Object
中,因此当您在此上下文中调用require
时,不一定{ 1}}模块正在处理该语句。
更新
我不确定这是否能完全解决您的问题,但不会受到以下所示奇怪行为的困扰:
Kernel
老答案:
这是不正确的,由于收到的赞成票,仅用于后代。一些没有file = 'non-existent-file'
allow(self).to receive(:require).with(file).and_return(true)
expect(self).to receive(:require).with(file)
expect(require file).to eq(true)
的工作方式。如果有人可以解释我为什么应该提出来,为什么会喜欢。我认为该问题与allow
有关,这不是预期的一部分。我的猜测是,我们仅测试自己收到的and_return
,require
,并且with_file
部分只是消息传输(因此是我更新的答案)
您仍然可以像这样存根:
and_return
由于我对您的确切实现方式尚不清楚,因为您对这个问题感到困惑,所以我无法解决您的确切问题。