我正在使用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(...)

最佳答案

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

试着抓

我们可以简单地使用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,因为测试代码既可读又灵活。但是,如果正确使用,所有其他提到的方法也是有效的。

10-02 23:53