Java JUnit 5:如何断言抛出异常?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40268446/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 22:34:04  来源:igfitidea点击:

JUnit 5: How to assert an exception is thrown?

javajunitjunit5junit-jupiter

提问by steventrouble

Is there a better way to assert that a method throws an exception in JUnit 5?

有没有更好的方法来断言 JUnit 5 中的方法抛出异常?

Currently, I have to use an @Rule in order to verify that my test throws an exception, but this doesn't work for the cases where I expect multiple methods to throw exceptions in my test.

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

采纳答案by steventrouble

You can use assertThrows(), which allows you to test multiple exceptions within the same test. With support for lambdas in Java 8, this is the canonical way to test for exceptions in JUnit.

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

Per the JUnit docs:

根据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().contains("Stuff"));
}

回答by Peter Isberg

Actually I think there is a error in the documentation for this particular example. The method that is intended is expectThrows

实际上,我认为此特定示例的文档中存在错误。预期的方法是 expectThrows

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

回答by jstar

They've changed it in JUnit 5 (expected: InvalidArgumentException, actual: invoked method) and code looks like this one:

他们在 JUnit 5 中对其进行了更改(预期:InvalidArgumentException,实际:调用方法),代码如下所示:

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

回答by Will Humphreys

You can use assertThrows(). My example is taken from the docs http://junit.org/junit5/docs/current/user-guide/

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

回答by prime

In Java 8 and JUnit 5 (Jupiter) we can assert for exceptions as follows. Using org.junit.jupiter.api.Assertions.assertThrows

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

public static < T extends Throwable > T assertThrows(Class< T > expectedType, Executable executable)

Asserts that execution of the supplied executable throws an exception of the expectedType and returns the exception.

If no exception is thrown, or if an exception of a different type is thrown, this method will fail.

If you do not want to perform additional checks on the exception instance, simply ignore the return value.

public static < T extends Throwable > T assertThrows(Class< T > expectedType, Executable executable)

断言所提供的可执行文件的执行会引发预期类型的​​异常并返回异常。

如果没有抛出异常,或者抛出了不同类型的异常,则此方法将失败。

如果您不想对异常实例执行额外检查,只需忽略返回值即可。

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

That approach will use the Functional Interface Executablein org.junit.jupiter.api.

这一方法将使用功能接口Executableorg.junit.jupiter.api

Refer :

参考 :

回答by Anupama Boorlagadda

Now Junit5 provides a way to assert the exceptions

现在 Junit5 提供了一种方法来断言异常

You can test both general exceptions and customized exceptions

您可以测试一般异常和自定义异常

A general exception scenario:

一般异常场景:

ExpectGeneralException.java

预期通用异常.java

public void validateParameters(Integer param ) {
    if (param == null) {
        throw new NullPointerException("Null parameters are not allowed");
    }
}

ExpectGeneralExceptionTest.java

ExpectGeneralExceptionTest.java

@Test
@DisplayName("Test assert NullPointerException")
void testGeneralException(TestInfo testInfo) {
    final ExpectGeneralException generalEx = new ExpectGeneralException();

     NullPointerException exception = assertThrows(NullPointerException.class, () -> {
            generalEx.validateParameters(null);
        });
    assertEquals("Null parameters are not allowed", exception.getMessage());
}

You can find a sample to test CustomException here : assert exception code sample

您可以在此处找到测试 CustomException 的示例:断言异常代码示例

ExpectCustomException.java

预期自定义异常.java

public String constructErrorMessage(String... args) throws InvalidParameterCountException {
    if(args.length!=3) {
        throw new InvalidParameterCountException("Invalid parametercount: expected=3, passed="+args.length);
    }else {
        String message = "";
        for(String arg: args) {
            message += arg;
        }
        return message;
    }
}

ExpectCustomExceptionTest.java

ExpectCustomExceptionTest.java

@Test
@DisplayName("Test assert exception")
void testCustomException(TestInfo testInfo) {
    final ExpectCustomException expectEx = new ExpectCustomException();

     InvalidParameterCountException exception = assertThrows(InvalidParameterCountException.class, () -> {
            expectEx.constructErrorMessage("sample ","error");
        });
    assertEquals("Invalid parametercount: expected=3, passed=2", exception.getMessage());
}

回答by JesseBoyd

I think this is an even simpler example

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

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

Calling get()on an optional containing an empty ArrayListwill throw a NoSuchElementException. assertThrowsdeclares the expected exception and provides a lambda supplier (takes no arguments and returns a value).

调用get()包含空的可选项ArrayList将抛出一个NoSuchElementException. assertThrows声明预期的异常并提供一个 lambda 供应商(不带参数并返回一个值)。

Thanks to @prime for his answer which I hopefully elaborated on.

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

回答by kiwicomb123

Here is an easy way.

这是一个简单的方法。

@Test
void exceptionTest() {

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

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

}

It only succeeds when the Exception you expect is thrown.

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

回答by rnyunja

An even simpler one liner. No lambda expressions or curly braces required for this example using Java 8 and JUnit 5

一个更简单的一个班轮。此示例使用 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()
}