Макет системного вызова в рубине - PullRequest
18 голосов
/ 27 октября 2009

Знаешь способ издеваться над% []? Я пишу тесты для кода, который выполняет несколько системных вызовов, например:

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

и хотел бы избежать фактического выполнения системных вызовов при тестировании этого метода. В идеале я хотел бы посмеяться над% x [..] и утверждать, что ему передана правильная команда оболочки.

Ответы [ 5 ]

17 голосов
/ 27 октября 2009

%x{…} - это встроенный синтаксис Ruby, который фактически вызывает метод ядра Backtick (`) . Таким образом, вы можете переопределить этот метод. Поскольку метод backtick возвращает стандартный результат выполнения cmd в подоболочке, ваш переопределенный метод должен возвращать нечто похожее на это, например, строку.

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

puts %x(ls)
puts `ls`
# output
# call ls
# call ls
13 голосов
/ 22 декабря 2009

Используя Мокко , если вы хотите посмеяться над следующим классом:

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 и `от объекта Kernel.

3 голосов
/ 27 октября 2009

Боюсь, я не знаю, как издеваться над модулем. По крайней мере, с Мокко 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
0 голосов
/ 27 октября 2009

Как насчет записи его в текстовый файл или вывода на консоль?

def log(file)
  puts "git log #{file}"
end
0 голосов
/ 27 октября 2009

Разве вы не можете просто переопределить функцию методом, который возвращает true, когда она получает команду?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...