使用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捕获该异常,并重新引发一个不同的异常。这个异常与我的异常有相同的消息[这个消息是我应该在测试中验证的],但是不同的班级。)
答案 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是开源的!