在JUnit 5中是否有更好的方法断言方法抛出异常?

目前,我必须使用@Rule来验证我的测试是否抛出异常,但这不适用于我希望多个方法在测试中抛出异常的情况。


当前回答

您可以使用assertThrows()。我的例子取自文档http://junit.org/junit5/docs/current/user-guide/

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

....

@Test
void exceptionTesting() {
    Throwable exception = assertThrows(IllegalArgumentException.class, () -> {
        throw new IllegalArgumentException("a message");
    });
    assertEquals("a message", exception.getMessage());
}

其他回答

您可以使用assertThrows(),它允许您在同一个测试中测试多个异常。由于Java 8支持lambdas,这是JUnit中测试异常的规范方法。

根据JUnit文档:

import static org.junit.jupiter.api.Assertions.assertThrows;

@Test
void exceptionTesting() {
    MyException thrown = assertThrows(
           MyException.class,
           () -> myObject.doThing(),
           "Expected doThing() to throw, but it didn't"
    );

    assertTrue(thrown.getMessage().contentEquals("Stuff"));
}

实际上,我认为这个特殊例子的文档中有一个错误。预期的方法是expectThrows

public static void assertThrows(
public static <T extends Throwable> T expectThrows(
This is what I do when testing to make sure an exception has been thrown

    
    //when
    final var tripConsumer = new BusTripConsumer(inputStream);
    final Executable executable = () -> tripConsumer.deserialiseTripData();

    //then
    assertThrows(IllegalArgumentException.class, executable);

我的解决方案:

    protected <T extends Throwable> void assertExpectedException(ThrowingRunnable methodExpectedToFail, Class<T> expectedThrowableClass,
        String expectedMessage) {
    T exception = assertThrows(expectedThrowableClass, methodExpectedToFail);
    assertEquals(expectedMessage, exception.getMessage());
}

你可以这样称呼它:

    assertExpectedException(() -> {
        carService.findById(id);
    }, IllegalArgumentException.class, "invalid id");

他们在JUnit 5中改变了它(预期:InvalidArgumentException,实际:invoked method),代码看起来像这样:

@Test
public void wrongInput() {
    Throwable exception = assertThrows(InvalidArgumentException.class,
            ()->{objectName.yourMethod("WRONG");} );
}