我正在编写一个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);
这看起来很丑陋,感觉可以改进 - 有更好的方法吗?
答案 0 :(得分:2)
我认为你应该在整个项目中保持一致 - 尽管有三种或四种不同的方法来解决这个问题,你绝对应该不尝试使用它们。
由于ExpectedException
机制是最强大,最通用的方式,我建议您学会使用它。它的优点包括以下内容。
expect
调用放在您希望抛出异常的行之前,确切地检查测试的哪一行引发异常。冒着听起来像洗发水广告的风险 - 现在我已经使用了ExpectedException
,我就不会使用其他任何东西了!
答案 1 :(得分:1)
没有最好的办法。这取决于:-)看一下JUnit Wiki:https://github.com/junit-team/junit/wiki/Exception-testing
答案 2 :(得分:1)
这里只是一个附加组件。我同意Stefan的帖子,这是一个很好的资源。以下是我遵循的指南。
如果测试中只有一个方法调用,那么我只使用@Test(expected=...)
,这是测试中的方法。这是因为以下内容......如果您有@Test(expect=NullPointerException.class)
并且在测试设置中某处出现了引发此异常的错误,该怎么办?测试将从未调用过测试方法。
因此,在所有其他情况下,我在调用测试方法之前立即使用ExpectedException
规则和expect
。这样,如果在方法调用之前代码中抛出异常,则测试将失败。
我从不使用捕获/失败机制,因为对于没有经验的人来说,删除fail
太容易了,这会让测试错误地通过。如果我需要进行额外验证,我仍然使用ExpectedException
并在完成任何其他验证后重新抛出catch块中的异常。