在 Java 中,如何验证 JUnit 抛出的异常?
为 Java API 编写单元测试时,有时您可能希望对异常执行更详细的验证。 即比 JUnit 提供的 @test 注释提供的更多。
例如,考虑一个类应该从其他接口捕获异常,包装该异常并抛出包装的异常。 您可能想要验证:
- 引发包装异常的确切方法调用。
- 包装器异常将原始异常作为其原因。
- 包装器异常的消息。
这里的要点是,您希望在单元测试中对异常进行额外的验证(而不是关于您是否应该验证异常消息之类的内容的争论)。
对此有什么好的方法吗?
When writing unit tests for a Java API there may be circumstances where you want to perform more detailed validation of an exception. I.e. more than is offered by the @test annotation offered by JUnit.
For example, consider an class that should catch an exception from some other Interface, wrap that exception and throw the wrapped exception. You may want to verify:
- The exact method call that throws the wrapped exception.
- That the wrapper exception has the original exception as its cause.
- The message of the wrapper exception.
The main point here is that you want to be perf additional validation of an exception in a unit test (not a debate about whether you should verify things like the exception message).
What's a good approach for this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
在 JUnit 4 中,可以使用 ExpectedException 规则轻松完成。
这是 javadocs 中的示例:
In JUnit 4 it can be easily done using ExpectedException rule.
Here is example from javadocs:
如您的答案<中提供的/a>,这是一个好方法。 除此之外:
您可以将函数
expectException
包装到一个新的注释中,称为ExpectedException
。带注释的方法看起来像这样:
这种方式会更具可读性,但它是完全相同的方法。
另一个原因是:我喜欢注释:)
As provided in your answer, it's a good approach. In addition to this:
You could wrap the function
expectException
into a new Annotation, calledExpectedException
.An annotated method would look like this:
This way would be more readable, but it's exactly the same approach.
Another reason is: I like Annotations :)
看看建议的答案,你可以真正感受到 Java 中没有闭包的痛苦。 恕我直言,最易读的解决方案是古老的 try catch。
Looking at the proposed answers, you can really feel the pain of not having closures in Java. IMHO, the most readable solution is ye good old try catch.
对于 JUNIT 3.x
For JUNIT 3.x
在这篇文章之前,我已经通过这样做完成了异常验证:
不过,我花了一些时间思考这个问题,并提出了以下建议(Java5,JUnit 3.x):
看着这两个,我无法决定哪一个我想要更多。 我想这是实现目标的问题之一(在我的例子中,带有仿函数参数的断言方法)从长远来看是不值得的,因为执行 6+ 代码来断言 try 会容易得多..catch 块。
话又说回来,也许我周五晚上 10 分钟解决问题的结果并不是最明智的方法。
Until this post I've done my exception validation by doing this:
I spent a few moments thinking about the issue though and came up with the following (Java5, JUnit 3.x):
Looking at these two I can't decide which one I like more. I guess this is one of those issues where achieving a goal (in my case, the assertion method with functor parameter) isn't worth it in the long run since it's just a lot easier to do those 6+ of code to assert the try..catch block.
Then again, maybe my 10 minute result of problem solving at friday evening just isn't the most intelligent way to do this.
@akuhn:
即使没有闭包,我们也可以获得更具可读性的解决方案(使用 catch-exception ):
@akuhn:
Even without closures we can get a more readable solution (using catch-exception):
以下帮助程序方法(改编自这篇博客文章)技巧:
测试代码可以按如下方式调用它:
The following helper method (adapted from this blog post) does the trick:
The test code can then invoke this as follows:
我做了一些非常简单的事情
i did something very simple
对于 JUnit 5 来说要容易得多:
通过返回异常对象本身,
assertThrows()
允许您测试有关抛出异常的各个方面。For JUnit 5 it is much easier:
By returning the exception object itself,
assertThrows()
allows you to test every aspect regarding your thrown exceptions.我制作了一个与其他发布的类似的助手:
客户端应该实现的模板
客户端代码将是这样的:
它看起来非常冗长,但如果您使用具有良好自动完成功能的 IDE,您只需要编写以下类型异常和被测试的实际代码。 (其余的将由 IDE 完成:D)
I made a helper similar to the other posted ones:
And the template the client should implement
And the client code would be something like this:
It looks really verbose but if you use an IDE with good autocompletion you will only need to write the type of exception and the actual code under test. (the rest will be done by the IDE :D)