8

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

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 进行测试。)

4

3 回答 3

10

编辑:使用丹尼斯威廉姆森的建议:

command = "(exit 21)"

并使用if $?.exitstatus == 0而不是if $? == 0

于 2011-01-03T23:58:38.730 回答
1
module Stubbed
  def `(*args)
    super( "mycommand that returns the error code I want" )
  end
end

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

于 2011-01-04T00:07:34.053 回答
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
于 2018-12-19T13:06:33.380 回答