1

使用 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. A 引发 MyException,但是 B 捕获该异常,并重新引发不同的异常。此异常与我的异常具有相同的消息 [并且此消息是我应该在测试中验证的内容],但属于不同的类。 )

4

2 回答 2

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

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

于 2013-07-24T04:16:23.043 回答
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不会工作。它必须是您在异常中混入的常见事物。

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

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

  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

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

所以..如果您的异常混合在一个模块中,您可以在模块上断言.. 但除此之外,请使用@vgoff 的答案.. 或扩展 minitest 以执行您想要的操作。

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

于 2013-07-24T07:33:26.390 回答