假设我有一个非常简单的Rake任务:
task :test do
system "bundle exec rspec spec"
end
我尝试通过存根::Kernel.system
方法调用来测试它:
describe "test" do
before { allow(::Kernel).to receive(:system) }
it "runs 'bundle exec rspec spec'" do
expect(::Kernel).to receive(:system).with "bundle exec rspec spec"
Rake::Task[:test].invoke
end
end
但这种方法似乎根本没有被删除。相反,我遇到了调用测试套件的无限循环迭代。
它有什么问题,以及如何正确调用系统?
答案 0 :(得分:4)
请注意Kernel
是一个包含在每个ruby Object
中的模块。 Kernel#system
是一个实例方法(不是类方法)。
一个解决方案(尽管discouraged by rspec maintainers)是使用"任何实例":
it "runs 'bundle exec rspec spec'" do
expect_any_instance_of(Kernel).to receive(:system).with "bundle exec rspec spec"
Rake::Task[:test].invoke
end
要使用常规expect
或allow
,您需要接收邮件的对象的实际实例。对于Rake任务来说,这将是繁琐的(虽然并非不可能 - 请参阅this question) - 它们是在顶层环境中执行的。
我建议您将system
调用封装到实用程序类方法中,并expect
封装。这将使测试更容易,你有明确的类和&与之合作的实例。