@Test(expected = Exception.class)或Assertions.assertThrows(...)或assertThatThrownBy(..)推荐哪个?

时间:2018-12-18 07:33:18

标签: java unit-testing junit

我正在使用JUnit 4.12

<dependency>
    <groupId>pl.pragmatists</groupId>
    <artifactId>JUnitParams</artifactId>
    <version>1.0.5</version>
    <scope>test</scope>
</dependency>

我想知道最推荐使用哪一个 @Test(expected = Exception.class)Assertions.assertThrows(...)

2 个答案:

答案 0 :(得分:0)

使用JUnit 4.12,有几种方法可以测试代码中的预期异常。

try-catch

我们可以简单地使用Java的try-catch。

@Test
public void testInvalidData() {
    prepareTestData();

    try {
        userService.fetchUser(1234);
        Assert.fail("IllegalArgumentException not thrown");
    } catch (IllegalArgumentException expected) {
    }
}

无论何时使用这种方法,都必须确保调用Assert.fail(...),以防未引发预期的异常。

注释属性

正如您已经提到的,@Test具有用于声明预期异常的属性。

@Test(expected = IllegalArgumentException.class)
public void testInvalidData() {
    prepareTestData();

    // should throw IllegalArgumentException
    userService.fetchUser(1234);
}

如果测试方法引发异常,则测试为绿色。如果测试方法未引发异常或其他异常,则该测试为红色。

这有一个很大的缺点:我们无法确定哪条指令引发了IllegalArgumentException。如果prepareTestData();抛出异常,则测试仍为绿色。

规则ExpectedException

JUnit 4包含内置规则ExpectedException。 (请记住,JUnit 5使用扩展而不是规则)

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

@Test
public void testInvalidData() {
    prepareTestData();

    thrown.expect(IllegalArgumentException.class);
    userService.fetchUser(1234);
}

这种方法类似于try-catch和@Test(expected = ...),但是我们可以控制从哪一点开始预期出现异常。

assertThrows

AssertJ和JUnit 5提供了断言特定代码块引发特定异常的方法。

@Test
public void testInvalidData() {
    prepareTestData();

    Assertions.assertThrows(IllegalArgumentException.class, () -> {
        userService.fetchUser(1234);
    });
}

Assertions.assertThrows还返回异常对象以执行进一步的断言,例如声明消息。

摘要

我尝试尽可能多地使用assertThrows,因为测试代码既可读又灵活。但是,如果使用得当,所有其他提到的方法也是有效的。

答案 1 :(得分:0)

expectedExceptions来自Test类家族,assertThrows来自Assert类家族。如果未从测试中的方法引发预期的异常,则两者都将失败。

文档中的预期异常:

/**
 * The list of exceptions that a test method is expected to throw.  If no
 * exception or a different than one on this list is thrown, this test will be
 * marked a failure.
 */
public Class[] expectedExceptions() default {};

assertThrows的文档

/**
 * Asserts that {@code runnable} throws an exception when invoked. If it does not, an
 * {@link AssertionError} is thrown.
 *
 * @param runnable A function that is expected to throw an exception when invoked
 * @since 6.9.5
 */

它们两个都翻译为:

try {
        ....
} catch (SomeException e) {

}

expectedExceptions可以包含多个Exception实例。 assertThrows()可以替代ExpectedException(这是最新的)。当您必须在assertThrows之后继续时,这更有意义。