为带出口完成的错误条件编写RSPEC测试



我正在为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脚本检测到导致退出条件的错误代码,这对我的宝石非常重要。

这种方法和整个策略都可以正常工作。但是我必须承认,我在不首先编写测试的情况下写了这一切。我知道,我知道...对我感到羞耻!

现在我已经完成了宝石,我想提高代码覆盖率。其他所有内容都是由本书完成的,首先编写测试和测试后代码。因此,对这些错误条件也有测试是很棒的。

当我使用exit中断处理时,我真的不知道如何为这种特定情况编写RSPEC测试。有什么建议吗?

UPDATE =>此GEM是装满Bash脚本的"编程环境"的一部分。其中一些脚本需要确切知道错误的条件,这打断了命令的执行。

例如:

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中获取绿色信号。

最新更新