Assert an Exception is Thrown in JUnit 4 and 5 – 在JUnit 4和5中断言一个异常被抛出

最后修改: 2018年 4月 13日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.绪论

In this quick tutorial, we’ll be looking at how to test if an exception was thrown using the JUnit library.

在这个快速教程中,我们将看看如何使用JUnit库来测试是否抛出了一个异常。

We will, of course, make sure to cover both the JUnit 4 and JUnit 5 versions.

当然,我们将确保涵盖JUnit 4和JUnit 5两个版本。

2. JUnit 5

2.JUnit 5

JUnit 5 Jupiter assertions API introduces the assertThrows method for asserting exceptions.

JUnit 5 Jupiter断言API引入了用于断言异常的assertThrows 方法。

This takes the type of the expected exception and an Executable functional interface where we can pass the code under test through a lambda expression:

这需要预期异常的类型和一个Executable功能接口,我们可以通过一个lambda表达式来传递被测代码。

@Test
public void whenExceptionThrown_thenAssertionSucceeds() {
    Exception exception = assertThrows(NumberFormatException.class, () -> {
        Integer.parseInt("1a");
    });

    String expectedMessage = "For input string";
    String actualMessage = exception.getMessage();

    assertTrue(actualMessage.contains(expectedMessage));
}

If the expected exception is thrown, assertThrows returns the exception, which enables us to also assert on the message.

如果预期的异常被抛出assertThrows返回异常,这使得我们也可以对消息进行断言。

Furthermore, it’s important to note that this assertion is satisfied when the enclosed code throws an exception of type NumberFormatException or any of its derived types.

此外,需要注意的是,当所附的代码抛出一个NumberFormatException类型或其任何派生类型的异常时,该断言得到满足。

This means that if we pass Exception as the expected exception type, any exception thrown will make the assertion succeed since Exception is the super-type for all exceptions.

这意味着如果我们传递Exception作为预期的异常类型,任何抛出的异常都会使断言成功,因为Exception是所有异常的超级类型。

If we change the test above to expect a RuntimeException, this will also pass:

如果我们把上面的测试改为期待一个RuntimeException,这也会通过。

@Test
public void whenDerivedExceptionThrown_thenAssertionSucceeds() {
    Exception exception = assertThrows(RuntimeException.class, () -> {
        Integer.parseInt("1a");
    });

    String expectedMessage = "For input string";
    String actualMessage = exception.getMessage();

    assertTrue(actualMessage.contains(expectedMessage));
}

The assertThrows() method enables more fine-grained control for exception assertion logic because we can use it around specific parts of the code.

assertThrows()方法能够对异常断言逻辑进行更精细的控制,因为我们可以围绕代码的特定部分使用方法。

3. JUnit 4

3.JUnit 4

When using JUnit 4, we can simply use the expected attribute of the @Test annotation to declare that we expect an exception to be thrown anywhere in the annotated test method.

当使用JUnit 4时,我们可以简单地使用@Test注解的期望属性来声明我们期望在注解的测试方法的任何地方抛出一个异常。

As a result, when the test is run, it will fail if the specified exception isn’t thrown and will pass if it’s thrown:

因此,当测试运行时,如果没有抛出指定的异常,它就会失败,如果抛出了,就会通过。

@Test(expected = NullPointerException.class)
public void whenExceptionThrown_thenExpectationSatisfied() {
    String test = null;
    test.length();
}

In this example, we’ve declared that we’re expecting our test code to result in a NullPointerException.

在这个例子中,我们已经声明,我们期望我们的测试代码会导致一个NullPointerException

This is enough if we’re only interested in asserting that an exception is thrown.

如果我们只对断言一个异常被抛出感兴趣,这就足够了。

When we need to verify some other properties of the exception, we can use the ExpectedException rule.

当我们需要验证异常的一些其他属性时,我们可以使用ExpectedException规则。

Let’s see an example of verifying the message property of an exception:

让我们看一个验证异常的message属性的例子。

@Rule
public ExpectedException exceptionRule = ExpectedException.none();

@Test
public void whenExceptionThrown_thenRuleIsApplied() {
    exceptionRule.expect(NumberFormatException.class);
    exceptionRule.expectMessage("For input string");
    Integer.parseInt("1a");
}

In the example above, we’re first declaring the ExpectedException rule. Then in our test, we’re asserting that the code that attempts to parse an Integer value will result in a NumberFormatException with the message “For input string”.

在上面的例子中,我们首先声明了ExpectedException规则。然后在我们的测试中,我们断言试图解析Integer值的代码将导致一个NumberFormatException,信息是 “For input string”。

4. Conclusion

4.总结

In this article, we covered asserting exceptions with both JUnit 4 and JUnit 5.

在这篇文章中,我们介绍了用JUnit 4和JUnit 5断言异常。

The full source code for the examples is available over on GitHub.

例子的完整源代码可在GitHub上获得over