本文翻译自JUnit 5 Expected Exception: How to assert an exception is thrown?

JUnit 5 Service Error

在本文中,我们将学习如何使用JUnit 5断言抛出异常以及如何检查抛出异常的错误消息。

本文是JUnit 5 教程的一部分。

概览

为了确保我们的错误处理逻辑正常工作,验证一段代码在某些条件下是否出发特定异常是有必要的。

断言抛出异常

断言一段代码抛出特定的异常可通过使用JUnit 5中的assertThrows()方法来完成:

1
2
3
4
5
6
@Test
void notEnoughFunds() {
    BankAccount account = new BankAccount(9);
    assertThrows(NotEnoughFundsException.class, () -> account.withdraw(10),
            "Balance must be greater than amount of withdrawal");
}

在此示例中,如果我们尝试从帐户余额允许的银行帐户中提取更多资金,则相关代码实现会抛出NotEnoughFundsException异常。

失败的断言

现在,假设在我们的示例中忘记在提款前检查余额,如果不抛出异常,测试将失败并显示错误消息:

1
2
Balance must be greater than amount of withdrawal ==> Expected com.arhohuttunen.junit5.exception.NotEnoughFundsException to be thrown, but nothing was thrown.
org.opentest4j.AssertionFailedError: Balance must be greater than amount of withdrawal ==> Expected com.arhohuttunen.junit5.exception.NotEnoughFundsException to be thrown, but nothing was thrown.

此外,假设在我们的示例中我们忘记初始化余额,代码将抛出NullPointerException异常,如果抛出非预期异常,测试将失败并显示不同的错误消息:

1
2
Balance must be greater than amount of withdrawal ==> Unexpected exception type thrown ==> expected: <com.arhohuttunen.junit5.exception.NotEnoughFundsException> but was: <java.lang.NullPointerException>
org.opentest4j.AssertionFailedError: Balance must be greater than amount of withdrawal ==> Unexpected exception type thrown ==> expected: <com.arhohuttunen.junit5.exception.NotEnoughFundsException> but was: <java.lang.NullPointerException>

断言异常消息

此外,有时我们想要验证异常的一些信息,例如错误消息或原因,在这种情况下可以捕获抛出的异常:

1
2
3
4
5
6
@Test
void notEnoughFundsWithMessage() {
    BankAccount account = new BankAccount(0);
    Throwable thrown = assertThrows(NotEnoughFundsException.class, () -> account.withdraw(100));
    assertEquals("Attempted to withdraw 100 with a balance of 0", thrown.getMessage());
}

总结

JUnit 5可以轻松断言使用assertThrows()方法引出发预期的异常,此外也可以捕获抛出的异常以检查错误消息等更多信息。

本文的示例代码能在GitHub中找到。