如何测试来自 rake 任务的系统调用
How to test system calls from the rake task
假设我有一个非常简单的 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
但是方法好像一点都不卡。相反,我 运行 进入调用测试套件的无限迭代循环。
它有什么问题,如何正确存根系统调用?
请注意 Kernel
是包含在每个 ruby Object
中的模块。 Kernel#system
是实例方法(不是 class 方法)。
一个解决方案(尽管 discouraged by rspec maintainers)是使用 "Any instance":
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
调用封装到实用程序 class 方法和 expect
方法中。这将使测试更容易,并且您可以使用明确的 classes 和实例。
假设我有一个非常简单的 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
但是方法好像一点都不卡。相反,我 运行 进入调用测试套件的无限迭代循环。
它有什么问题,如何正确存根系统调用?
请注意 Kernel
是包含在每个 ruby Object
中的模块。 Kernel#system
是实例方法(不是 class 方法)。
一个解决方案(尽管 discouraged by rspec maintainers)是使用 "Any instance":
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
调用封装到实用程序 class 方法和 expect
方法中。这将使测试更容易,并且您可以使用明确的 classes 和实例。