代码之家  ›  专栏  ›  技术社区  ›  dstnbrkr

ruby中的模拟系统调用

  •  18
  • dstnbrkr  · 技术社区  · 15 年前

    知道如何嘲笑“%[]?我正在为进行一些系统调用的代码编写测试,例如:

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

    并希望在测试此方法时避免实际执行系统调用。理想情况下,我希望模拟%x[…]并断言已将正确的shell命令传递给它。

    5 回复  |  直到 15 年前
        1
  •  17
  •   pierrotlefou    15 年前

    %x{…} 是ruby内置的语法,它实际上会调用内核方法 Backtick (`) . 所以你可以重新定义这个方法。由于backtick方法返回在子shell中运行cmd的标准输出,重新定义的方法应该返回类似的内容,例如字符串。

    module Kernel
        def `(cmd)
            "call #{cmd}"
        end
    end
    
    puts %x(ls)
    puts `ls`
    # output
    # call ls
    # call ls
    
        2
  •  13
  •   Jippe    15 年前

    使用 Mocha ,如果要模拟到以下类:

    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和`之类的方法。

        3
  •  3
  •   Mike Woodhouse    15 年前

    恐怕我不知道如何模拟一个模块。至少用摩卡咖啡, 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
    

    这给了我希望:

    Started
    .
    Finished in 0.0 seconds.
    
    1 tests, 1 assertions, 0 failures, 0 errors
    
        4
  •  0
  •   JAL    15 年前

    把它记录到一个文本文件,或者输出到您的控制台怎么样?

    def log(file)
      puts "git log #{file}"
    end
    
        5
  •  -1
  •   CodeJoust    15 年前

    你不能用一个方法返回函数,当它得到命令时返回true吗?