2009-10-27 85 views
15

知道一種方法來模擬%[]?我正在寫代碼測試,使得一些系統調用,例如:模擬系統調用紅寶石

def log(file) 
    %x[git log #{file}] 
end 

,並想避免實際執行系統調用在測試這種方法。理想情況下,我想模擬%x [..]並聲明正確的shell命令被傳遞給它。

回答

17

%x{…}是Ruby的內置語法,將實際調用內核方法Backtick (`)。所以你可以重新定義這個方法。由於反向方法在子shell中返回正在運行的cmd的標準輸出,所以重新定義的方法應該返回類似的內容,例如字符串。

module Kernel 
    def `(cmd) 
     "call #{cmd}" 
    end 
end 

puts %x(ls) 
puts `ls` 
# output 
# call ls 
# call ls 
0

難道你不能只用一個返回true的方法來獲取命令時使用ovverride函數嗎?

0

如何將其記錄到文本文件或將其輸出到控制檯?

def log(file) 
    puts "git log #{file}" 
end 
3

我不知道嘲笑模塊的方法,恐怕。至少用摩卡,Kernel.expects沒有幫助。您可以總是包裹調用的類和模擬的是,這樣的事情:

require 'test/unit' 
require 'mocha' 

class SystemCaller 
    def self.call(cmd) 
    system cmd 
    end 
end 

class TestMockingSystem < Test::Unit::TestCase 
    def test_mocked_out_system_call 
    SystemCaller.expects(:call).with('dir') 
    SystemCaller.call "dir" 
    end 
end 

這給了我什麼,我倒是希望爲:使用Mocha

Started 
. 
Finished in 0.0 seconds. 

1 tests, 1 assertions, 0 failures, 0 errors 
12

,如果你想模擬到下面的類:

class Test 
    def method_under_test 
    system "echo 'Hello World!" 
    `ls -l` 
    end 
end 

您的測試看起來是這樣的:

def test_method_under_test 
    Test.any_instance.expects(:system).with("echo 'Hello World!'").returns('Hello World!').once 
    Test.any_instance.expects(:`).with("ls -l").once 
end 

這是可行的,因爲每一個對象都繼承像system和`from內核對象的方法。

+0

至少:'版本與rspec 2 mocks一起工作以及 – 2011-10-26 01:59:18

+0

使用'should_receive'而不是'expect'' – 2013-12-07 00:11:45

+1

不適用於當前版本。 Minitest :: UnexpectedError:NoMethodError:未定義的方法'any_instance'for Test:Module;但是,如果我在對象上調用它,它會起作用。 – 2015-11-01 11:57:33