Макет системного вызова в рубине
Знать способ издеваться над% []? Я пишу тесты для кода, который выполняет несколько системных вызовов, например:
def log(file)
%x[git log #{file}]
end
и хотел бы избежать фактического выполнения системных вызовов при тестировании этого метода. В идеале я хотел бы высмеять% x [..] и утверждать, что правильная команда оболочки передается ему.
Ответы
Ответ 1
%x{…}
- это встроенный синтаксис Ruby, который на самом деле вызовет метод Kernel Backtick (`). Таким образом, вы можете переопределить этот метод. Когда метод backtick возвращает стандартный вывод работы cmd в подоболочке, ваш переопределенный метод должен возвращать нечто похожее на это, например строку.
module Kernel
def `(cmd)
"call #{cmd}"
end
end
puts %x(ls)
puts `ls`
# output
# call ls
# call ls
Ответ 2
Используя 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 и `от объекта Kernel.
Ответ 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
который дает мне то, на что я надеюсь:
Started
.
Finished in 0.0 seconds.
1 tests, 1 assertions, 0 failures, 0 errors
Ответ 4
Не можете ли вы просто переустановить функцию с помощью метода, который возвращает true, когда получает команду?
Ответ 5
Как записывать его в текстовый файл или выводить его на консоль?
def log(file)
puts "git log #{file}"
end