【问题标题】:How to get assert_raise to handle exception subclasses如何让 assert_raise 处理异常子类
【发布时间】:2013-12-16 18:03:29
【问题描述】:

有时我想要一个单元测试来确认某些代码引发了异常,而不知道确切的异常类。例如,为了确认它引发了 kind_of?(StandardError) 的异常,我想这样写:

assert_raise StandardError do
  my_method
end

如果异常是StandardError 的实例,则此断言通过,但如果异常是StandardError子类 实例,则失败。我最好的解决方案是:

begin
  my_method
rescue StandardError => error
  return
end
assert false, "no error from my_method"

rescue 确实按照我想要的方式处理异常子类,所以这是可行的。但这有点尴尬。有更好的想法吗?

这是 Ruby 1.8.7 中的 Test::Unit::Assertions 模块。

【问题讨论】:

    标签: ruby unit-testing exception assertions


    【解决方案1】:

    正如您在rubyforge bugtracker ticket [#8716] Add option to Test::Unit::Assertions#assert_raise to allow subclasses from 2007(!) 中看到的,这是一个仍然开放的功能请求。

    如果您非常需要该功能,您可以对其进行修补。

    【讨论】:

      【解决方案2】:

      这与您开始时的基本相同,但在 IMO 上更容易解释:

      begin
        my_method
      rescue => e
        # Could be any number of error classes: 
        # HTTPClient::ConnectTimeoutError, SocketError, etc.
        assert e.class.ancestors.include?(StandardError), "Expected my_method to raise a subclass of StandardError, but #{e.class} was raised"
        return
      end
      
      # Force the test to fail if no error was raised
      assert false, "Expected my_method to raise a subclass of StandardError, but no error was raised"
      

      【讨论】:

      • 为什么是e.class.ancestors.include?(StandardError)e.is_a? StandardError呢?
      【解决方案3】:

      据我所知,assert_raise 中的异常是可选的

      测试给定块是否引发异常。可接受的异常类型可以作为可选参数给出。

      你应该会写

      assert_raise { my_method }
      

      【讨论】:

      • 但是如果(比如说)引发了 SignalException,那么测试就会通过,对吧?这是一个异常,但不是标准错误,所以我希望它失败。
      • 我不明白这一点。是否要 assert_raise 检查错误是否为 StandardError 的实例?
      • 是的,StandardError 或其子类。我将进行编辑以使其更清晰。
      猜你喜欢
      • 2018-03-07
      • 2016-10-08
      • 1970-01-01
      • 2010-12-26
      • 2011-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-09
      相关资源
      最近更新 更多