【问题标题】:How to test system calls from the rake task如何测试来自 rake 任务的系统调用
【发布时间】:2015-04-01 06:57:06
【问题描述】:

假设我有一个非常简单的 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

但该方法似乎根本没有被存根。相反,我遇到了调用测试套件的无限循环迭代。

它有什么问题,以及如何正确地存根系统调用?

【问题讨论】:

    标签: ruby rspec rake system stub


    【解决方案1】:

    请注意,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
    

    为了使用常规的expectallow,您需要接收消息的对象的实际实例。对于 Rake 任务,这会很麻烦(尽管并非不可能 - 请参阅 this question) - 它们在顶级上下文中执行。

    我建议您将 system 调用封装到实用程序类方法和 expect 中。这将使测试更容易,并且您可以使用明确的类和实例。

    【讨论】:

    • 谢谢你,Łukasz,你拯救了我的一天!使用新的 RSpec 语法,我已经完全忘记了 'any_instance' 的旧语法。为了清楚起见,我只想说是 allow_any_instance 解决了这个问题。
    猜你喜欢
    • 2011-06-07
    • 2010-11-09
    • 2011-01-03
    • 1970-01-01
    • 2010-11-18
    • 2014-09-06
    • 1970-01-01
    • 2015-12-29
    • 2018-02-20
    相关资源
    最近更新 更多