2014-02-08 32 views
2

我有一些代碼可以調用Linux操作系統,它將運行特定於發行版的命令。我試圖確保測試可以在任何系統上運行,所以我使用一個測試雙擊來呼叫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 

我不明白爲什麼雙不希望:run_command當我明確地設置它以期待。我錯過了什麼?

回答

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 
+0

This Works!謝謝。我忘記了double是一個返回一個新的double的方法,而不僅僅是同一個實例。 +1還提醒我使用'subject'而不是實例化一個新實例。 – bbcmicro

+0

很好的答案! @bbcmicro請批准正確答案 – gotva

0

現在不能檢查,但在我看來,你需要存根:initialize方法 - 不是:new

試試這個變種:

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

打樁明確的構造函數有兩個作用:(1)警告:移除'初始化」可能會導致嚴重的問題,(2)故障:Mixlib試圖調用getenforce,這不存在,並且因此給出沒有這樣的文件或目錄錯誤。這告訴我們即使:new是initialize的別名,但該存根似乎只對明確調用的方法生效。 – bbcmicro

相關問題