为什么我的测试加倍不期望我允许的命令?

时间:2014-02-08 11:31:16

标签: ruby rspec mocking

我有一些代码可以对Linux操作系统进行shellout调用,后者将运行特定于发行版的命令。我正在尝试确保测试可以在任何系统上运行,因此我使用了Mixlib::ShellOut调用的双重测试。这是一个复制我的问题的简化版本:

require 'mixlib/shellout'
class SelinuxCommand
  def run
    runner = Mixlib::ShellOut.new('getenforce')
    runner.run_command
  end
end

我的测试存根Mixlib:ShellOut.new返回测试双精度,然后说:run_command应该返回字符串'Enforcing'

require 'rspec'
require_relative 'selinuxcommand'
describe SelinuxCommand do
  it 'gets the Selinux enforcing level' do
    command = SelinuxCommand.new
    Mixlib::ShellOut.stub(:new).and_return(double)
    allow(double).to receive(:run_command).and_return('Enforcing')
    expect command.run.to eql 'Enforcing'
  end
end

然而,当我运行测试时,我看到:

$ rspec -fd selinuxcommand_spec.rb

SelinuxCommand   gets the Selinux enforcing level (FAILED - 1)

Failures:

  1) SelinuxCommand gets the Selinux enforcing level
     Failure/Error: expect command.run.to eql 'Enforcing'
       Double received unexpected message :run_command with (no args)
     # ./selinuxcommand.rb:5:in `run'
     # ./selinuxcommand_spec.rb:9:in `block (2 levels) in <top (required)>'

Finished in 0.00197 seconds 1 example, 1 failure

Failed examples:

rspec ./selinuxcommand_spec.rb:5 # SelinuxCommand gets the Selinux enforcing level

我不明白为什么当我明确地将它设置为期望时,double不会期望:run_command。我错过了什么?

2 个答案:

答案 0 :(得分:2)

这只是因为每次调用double时都会得到一个不同的对象,因此允许接收run_command方法的对象与存根new返回的对象不同。你可以像这样解决它:

it 'Gets the Selinux enforcing level' do
  runner = double
  Mixlib::ShellOut.stub(:new).and_return(runner)

  expect(runner).to receive(:run_command).and_return('Enforcing')
  expect(subject.run).to eq('Enforcing')
end

答案 1 :(得分:0)

现在无法检查,但在我看来,您需要存根:initialize方法 - 而不是:new

尝试此变体:

Mixlib::ShellOut.stub(:initialize).and_return(double)