【问题标题】:How to verify the details of exceptions thrown in JUnit tests? [duplicate]如何验证 JUnit 测试中抛出的异常的详细信息? [复制]
【发布时间】:2013-11-19 08:54:39
【问题描述】:

我正在编写一个 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);

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

【问题讨论】:

标签: java unit-testing exception junit mockito


【解决方案1】:

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

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

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

冒着听起来像洗发水广告的风险——既然我用过ExpectedException,我就不会再用其他任何东西了!

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      1. 如果测试中只有一个方法调用并且就是被测方法,我只使用@Test(expected=...)。那是因为以下...如果从未调用过被测方法,测试将通过。

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-18
        • 2011-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-21
        相关资源
        最近更新 更多