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

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


当前回答

在Java 8和JUnit 5 (Jupiter)中,我们可以这样断言异常。 使用org.junit.jupiter.api.Assertions.assertThrows

public static < T extends Throwable > T assertThrows(类< T > expectedType, 可执行可执行) 断言所提供的可执行文件的执行将抛出expectedType的异常并返回该异常。 如果没有抛出异常,或者抛出了不同类型的异常,则此方法将失败。 如果您不想对异常实例执行额外的检查,只需忽略返回值。

@Test
public void itShouldThrowNullPointerExceptionWhenBlahBlah() {
    assertThrows(NullPointerException.class,
            ()->{
            //do whatever you want to do here
            //ex : objectName.thisMethodShoulThrowNullPointerExceptionForNullParameter(null);
            });
}

该方法将使用org.junit.jupiter.api中的函数接口可执行文件。

参考:

http://junit.org/junit5/docs/current/user-guide/#writing-tests-assertions http://junit.org/junit5/docs/5.0.0-M2/api/org/junit/jupiter/api/Executable.html http://junit.org/junit5/docs/5.0.0-M4/api/org/junit/jupiter/api/Assertions.html#assertThrows-java.lang.Class-org.junit.jupiter.api.function.Executable-

其他回答

您可以使用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"));
}

这里有一个简单的方法。

@Test
void exceptionTest() {

   try{
        model.someMethod("invalidInput");
        fail("Exception Expected!");
   }
   catch(SpecificException e){

        assertTrue(true);
   }
   catch(Exception e){
        fail("wrong exception thrown");
   }

}

它只有在抛出您期望的异常时才会成功。

更简单的一行代码。使用Java 8和JUnit 5,本例不需要lambda表达式或花括号

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

@Test
void exceptionTesting() {

    assertThrows(MyException.class, myStackObject::doStackAction, "custom message if assertion fails..."); 

// note, no parenthesis on doStackAction ex ::pop NOT ::pop()
}

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

public static void assertThrows(
public static <T extends Throwable> T expectThrows(

我认为这是一个更简单的例子

List<String> emptyList = new ArrayList<>();
Optional<String> opt2 = emptyList.stream().findFirst();
assertThrows(NoSuchElementException.class, () -> opt2.get());

在包含空数组列表的可选对象上调用get()将抛出NoSuchElementException异常。assertThrows声明预期的异常并提供lambda提供者(不接受参数并返回值)。

感谢@prime的回答,我希望能详细说明。