2009-10-27 83 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