检查是否有异常

时间:2013-07-24 03:04:28

标签: ruby minitest

使用MiniTest规范,我可以测试代码引发一个特定的异常,如下所示:

proc { foo.do_bar }.must_raise SomeException

但是,我不关心具体的异常是什么,我只是想验证是否抛出了某些异常。如果我或其他开发人员决定改变Foo#do_bar引发的异常,如果通常指定了预期的异常,我的测试就不必改变。

也就是说,我想用这种方式编写测试(Exception是SomeException类的祖先):

proc { foo.do_bar }.must_raise Exception

这导致我在运行测试时失败:

[Exception] exception expected, not
Class: <SomeException>

我能否就异常更一般地编写我的Minitest规范?

(我想检查任何异常而不是特定异常的实际原因是我使用的是第三方Gem,并且是引发异常的代码。事实上,我的方法A被调用通过第三方方法B.引发MyException,但是B捕获该异常,并重新引发一个不同的异常。这个异常与我的异常有相同的消息[这个消息是我应该在测试中验证的],但是不同的班级。)

2 个答案:

答案 0 :(得分:2)

describe 'testing' do
  it 'must raise' do
   a = Proc.new {oo.non_existant}
   begin
     a[]
   rescue => e
   end
   e.must_be_kind_of Exception
  end
end

无论如何,这应该与您要求的非常接近。

答案 1 :(得分:0)

这似乎很奇怪。

来自:http://bfts.rubyforge.org/minitest/MiniTest/Assertions.html#method-i-assert_raises

# File lib/minitest/unit.rb, line 337
def assert_raises *exp
  msg = "#{exp.pop}\n" if String === exp.last

  should_raise = false
  begin
    yield
    should_raise = true
  rescue MiniTest::Skip => e
    details = "#{msg}#{mu_pp(exp)} exception expected, not"

    if exp.include? MiniTest::Skip then
      return e
    else
      raise e
    end
  rescue Exception => e
    details = "#{msg}#{mu_pp(exp)} exception expected, not"
    assert(exp.any? { |ex|
             ex.instance_of?(Module) ? e.kind_of?(ex) : ex == e.class
           }, exception_details(e, details))

    return e
  end

  exp = exp.first if exp.size == 1
  flunk "#{msg}#{mu_pp(exp)} expected but nothing was raised." if
    should_raise
end

这检查传递的异常是Module的实例,如果是,则e.kind_of?(ex)使用SomeException可以正常工作,因为Exception的实例将属于ex但仅如果Exception是模块,那么 module MyModule; end class AnError < StandardError; include MyModule; end .... def test_assert_raises @tc.assert_raises RuntimeError do raise "blah" end end def test_assert_raises_module @tc.assert_raises MyModule do raise AnError end end 将无效。它必须是你在异常中混合的常见事物。

(如此处所示http://ruby-doc.org/core-2.0/Object.html#method-i-kind_of-3F

这与minitests自己的测试相匹配......

{{1}}

(来自:https://github.com/seattlerb/minitest/blob/master/test/minitest/test_minitest_unit.rb

所以..如果你的Exception混合在一个模块中,你可以在模块上断言..但除此之外用@vgoff的答案..或者扩展minitest来做你想要的。

注意:我喜欢ruby是开源的!