【问题标题】:Writing a Rspec test for an error condition finished with exit为退出完成的错误条件编写 Rspec 测试
【发布时间】:2016-12-30 07:04:09
【问题描述】:

我正在编写一个 Ruby gem 的命令行界面,我有这个方法 exit_error,它充当处理时执行的所有验证的退出错误点。

def self.exit_error(code,possibilities=[])
  puts @errormsgs[code].colorize(:light_red)
  if not possibilities.empty? then
    puts "It should be:"
    possibilities.each{ |p| puts "  #{p}".colorize(:light_green) }
  end
  exit code
end

其中@errormsgs 是一个哈希,其键是错误代码,其值是相应的错误消息。

这样我可以给用户自定义的错误消息,编写验证,例如:

exit_error(101,@commands) if not valid_command? command

地点:

@errormsgs[101] => "Invalid command." 
@commands = [ :create, :remove, :list ] 

并且用户输入错误的命令会收到如下错误消息:

Invalid command.
It should be:
  create
  remove
  list

同时,这样我可以让 bash 脚本准确检测导致退出条件的错误代码,这对我的 gem 非常重要。

使用这种方法和整个策略一切正常。但我必须承认,我在没有先写测试的情况下写了这一切。我知道,我知道……真丢脸!

现在我已经完成了 gem,我想提高我的代码覆盖率。其他一切都由本书完成,首先编写测试,然后编写代码。因此,对这些错误条件进行测试也很棒。

当我使用exit 中断处理时,碰巧我真的不知道如何针对这种特殊情况编写 Rspec 测试。有什么建议吗?

更新 => 这个 gem 是一个充满 bash 脚本的“编程环境”的一部分。其中一些脚本需要准确地知道中断命令执行的错误条件才能采取相应的行动。

【问题讨论】:

  • 你到底想用bash做什么?
  • @Inian 这个 gem 是“编程环境”的一部分,它有很多 bash 脚本。其中一些脚本需要知道这个 Ruby 命令行界面返回的错误代码,因此它们可以采取相应的行动。
  • $?可以获取任意命令的返回码,可以直接查看其值进行成功/失败检查。
  • 我知道,@Inian。但是正在执行的程序必须在exit 命令中指定错误代码。如果我只是提出一个错误来强制中断,我只会有一个非零返回码,表明程序发生了异常中断。我需要的不止这些。我需要指定许多不同的错误条件,并让 bash 以特定的方式处理每个错误条件。
  • 您的要求听起来不错,但您的输入无法验证,这里的人们需要最少的可验证输入和预期输出来帮助您编写代码。到目前为止,它没有帮助。

标签: ruby rspec error-handling exit


【解决方案1】:

例如:

class MyClass
  def self.exit_error(code,possibilities=[])
    puts @errormsgs[code].colorize(:light_red)
    if not possibilities.empty? then
      puts "It should be:"
      possibilities.each{ |p| puts "  #{p}".colorize(:light_green) }
    end
    exit code
  end
end

你可以把它的 rspec 写成这样:

describe 'exit_error' do
  let(:errormsgs) { {101: "Invalid command."} }
  let(:commands) { [ :create, :remove, :list ] }
  context 'exit with success'
    before(:each) do
      MyClass.errormsgs = errormsgs # example/assuming that you can @errormsgs of the object/class
      allow(MyClass).to receive(:exit).with(:some_code).and_return(true)
    end

    it 'should print commands of failures'
      expect(MyClass).to receive(:puts).with(errormsgs[101])
      expect(MyClass).to receive(:puts).with("It should be:")
      expect(MyClass).to receive(:puts).with(" create")
      expect(MyClass).to receive(:puts).with(" remove")
      expect(MyClass).to receive(:puts).with(" list")
      MyClass.exit_error(101, commands)
    end
  end

  context 'exit with failure'
    before(:each) do
      MyClass.errormsgs = {} # example/assuming that you can @errormsgs of the object/class
      allow(MyClass).to receive(:exit).with(:some_code).and_return(false)
    end

    # follow the same approach as above for a failure
  end
end

当然,这是您的规范的初始前提,如果您复制并粘贴代码,则可能无法正常工作。为了从 rspec 获得绿色信号,您必须进行一些阅读和重构。

【讨论】:

  • 谢谢!是的,我知道我必须适应,但你让我走上了正轨。我不知道如何启动它。
猜你喜欢
  • 2019-01-01
  • 2012-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-03
  • 1970-01-01
相关资源
最近更新 更多