Ruby 如何模拟或重写Kernel.system?

Ruby 如何模拟或重写Kernel.system?,ruby,mocking,testunit,Ruby,Mocking,Testunit,如何正确地模拟或重写Kernel.system方法,以便在使用以下方法调用时: system("some command") 它不是执行命令,而是执行一些预定义的代码 我尝试将以下内容添加到我的测试类: module Kernel def system puts "SYSTEM CALL!!" end end 但是它没有按预期工作,相反,系统调用是在执行测试时运行的。如果您谈论的是单元测试并使用Rspec,您应该能够这样做: Kernel.should_rec

如何正确地模拟或重写
Kernel.system
方法,以便在使用以下方法调用时:

system("some command")
它不是执行命令,而是执行一些预定义的代码

我尝试将以下内容添加到我的测试类:

module Kernel
    def system
        puts "SYSTEM CALL!!"
    end
end

但是它没有按预期工作,相反,系统调用是在执行测试时运行的。

如果您谈论的是单元测试并使用Rspec,您应该能够这样做:

Kernel.should_receive(:system)
expect(Kernel).to receive(:system).and_return(true)
require 'spec_helper'

describe FooComponent do
  let(:foo_component) { described_class.new }

  describe '#run' do
    it 'does some awesome things' do
      expect(foo_component).to receive(:system).with('....')
      foo_component.run
    end
  end
end
或者稍微松一点:

Kernel.stub(:system)

更多信息:

自提出此问题以来,RSpec 3推出了一种新的语法,您可以在其中编写以下内容:

expect(Kernel).to receive(:system)
如果代码检查系统调用是否成功,则可以如下指定结果:

Kernel.should_receive(:system)
expect(Kernel).to receive(:system).and_return(true)
require 'spec_helper'

describe FooComponent do
  let(:foo_component) { described_class.new }

  describe '#run' do
    it 'does some awesome things' do
      expect(foo_component).to receive(:system).with('....')
      foo_component.run
    end
  end
end
松散版本:

allow(Kernel).to receive(:system).and_return(true)

在某些情况下,仅执行
expect(内核)。接收(:系统)
是不够的

考虑这个例子:

foo_component.rb

class FooComponent
  def run
    system('....')
  end
end
foo_组件规格rb

require 'spec_helper'

describe FooComponent do
  let(:foo_component) { described_class.new }

  describe '#run' do
    it 'does some awesome things' do
      expect(Kernel).to receive(:system).with('....')
      foo_component.run
    end
  end
end
这是行不通的。这是因为
内核
是一个模块,
对象
(父类)混合在
内核
模块中,使得所有
内核
方法在“全局”范围内可用

这就是为什么正确的测试应该是这样的:

Kernel.should_receive(:system)
expect(Kernel).to receive(:system).and_return(true)
require 'spec_helper'

describe FooComponent do
  let(:foo_component) { described_class.new }

  describe '#run' do
    it 'does some awesome things' do
      expect(foo_component).to receive(:system).with('....')
      foo_component.run
    end
  end
end

若它在一个类中,那个么内核是混合的。因此,您可以将其模拟为对象的一部分

例如


我给你的链接来自官方rspec文档:。您也可以查看-它提供了一些关于如何正确使用rspec的最佳实践。谢谢!先生:)看起来不错。是的,我说的是单元测试,但不幸的是,代码没有使用rspec,而是使用简单的测试单元。在这种情况下,您应该看看:-
内核。期望(:系统)。返回(true)
是否应该接收(:方法\u名称)存根该方法以使其不被执行?或者您需要使用
.stub(:method_name)
来阻止它被执行吗?仅供参考,使用ruby 2.3.0和rspec core 3.4.2,我必须使用
Kernel.system(…)
而不是仅使用
system(…)
才能通过模拟。