有没有办法设置$的值?在Ruby中的模拟?

时间:2011-01-03 23:46:57

标签: ruby testing mocha

我正在测试一些与系统命令交互的脚本。它们的逻辑取决于系统命令的返回码,即$?的值。因此,作为简化示例,脚本可能会说:

def foo(command)
  output=`#{command}`
  if $?==0
    'succeeded'
  else
    'failed'
  end
end

为了能够正确地测试这些方法,我希望能够发出内核反引号调用,并设置$?到一个任意值,看看在反引号调用后我是否从方法中的逻辑得到了适当的行为。 $?是一个只读变量,因此以下内容不起作用:

$? = some_number

我可以做一些简单的事情:例如,设置$?为零或非零。例如,将设置$?到0或35212(在我的系统上,无论如何),取决于$?:

的值
def fail_or_succeed(success)
  if success
    `echo foo`
  else
    `a-non-existent-command 2>&1`
  end
end

我真正想做的是设置$?特定值(例如3或122),不仅是零或任意非零。我无法想办法做到这一点。 (如果重要,我正在使用Test :: Unit和Mocha进行测试。)

3 个答案:

答案 0 :(得分:10)

编辑:使用Dennis Williamson的建议:

command = "(exit 21)"

并使用if $?.exitstatus == 0代替if $? == 0

答案 1 :(得分:1)

module Stubbed
  def `(*args)
    super( "mycommand that returns the error code I want" )
  end
end

在需要时将其包含在您的对象中?

答案 2 :(得分:0)

您可以从测试中启动一个子流程,该子流程将随您需要的任何代码一起退出。这将为您设置$?.exitstatus代码,该代码将在生产代码中提供

对于这样的生产代码:

def execute_something
  `my_command --parameter`
  $?.exitstatus == 0
end

您可以嘲笑$?.exitstatus

it 'should return false' do
  fork { exit 1 } # Change to whatever code you need
  Process.wait

  expect(@sut).to receive(:`).with('my_command --parameter')
  expect(@sut.execute_something).to be == false
end