如何验证JUnit测试中抛出的异常的细节?

时间:2013-11-19 08:54:39

标签: java unit-testing exception junit mockito

我正在编写一个JUnit / Mockito测试,预计会抛出异常。我当然可以这样做:

@Test(expected=IllegalArgumentException.class)

但它扔掉之后我不会做任何其他事情。所以我想的可能更像是:

Exception actualEx = null;
try {
    // Act
    sut.doStuff();
} catch (final Exception ex) {
    actualEx = ex;
}
// Assert
assertTrue(IllegalArgumentException.class.equals(actualEx.getClass()));
// ... perhaps verify the exception details
verifyNoMoreInteractions(mockObject);

这看起来很丑陋,感觉可以改进 - 有更好的方法吗?

3 个答案:

答案 0 :(得分:2)

我认为你应该在整个项目中保持一致 - 尽管有三种或四种不同的方法来解决这个问题,你绝对应该尝试使用它们。

由于ExpectedException机制是最强大,最通用的方式,我建议您学会使用它。它的优点包括以下内容。

  • 很容易检查抛出的异常的类型及其消息。
  • 如果需要,您可以对异常进行更复杂的匹配。
  • 您可以通过将expect调用放在您希望抛出异常的行之前,确切地检查测试的哪一行引发异常。

冒着听起来像洗发水广告的风险 - 现在我已经使用了ExpectedException,我就不会使用其他任何东西了!

答案 1 :(得分:1)

没有最好的办法。这取决于:-)看一下JUnit Wiki:https://github.com/junit-team/junit/wiki/Exception-testing

答案 2 :(得分:1)

这里只是一个附加组件。我同意Stefan的帖子,这是一个很好的资源。以下是我遵循的指南。

  1. 如果测试中只有一个方法调用,那么我只使用@Test(expected=...),这是测试中的方法。这是因为以下内容......如果您有@Test(expect=NullPointerException.class)并且在测试设置中某处出现了引发此异常的错误,该怎么办?测试将从未调用过测试方法。

  2. 因此,在所有其他情况下,我在调用测试方法之前立即使用ExpectedException规则和expect。这样,如果在方法调用之前代码中抛出异常,则测试将失败。

  3. 我从不使用捕获/失败机制,因为对于没有经验的人来说,删除fail太容易了,这会让测试错误地通过。如果我需要进行额外验证,我仍然使用ExpectedException并在完成任何其他验证后重新抛出catch块中的异常。