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来验证我的测试是否会引发异常,但这对于我希望多个方法在我的测试中抛出异常的情况不起作用。
7 个解决方案
#1
74
You can use assertThrows()
, which allows you to test multiple exceptions within the same test. With support for lambdas in Java 8, this is probably going to become the canonical way to test for exceptions in JUnit.
您可以使用assertThrows(),它允许您在同一测试中测试多个异常。在Java 8中支持lambdas,这可能会成为在JUnit中测试异常的规范方法。
Per the JUnit docs:
根据JUnit文档:
import static org.junit.jupiter.api.Assertions.assertThrows;
...
@Test
void exceptionTesting() {
Executable closureContainingCodeToTest = () -> throw new IllegalArgumentException("a message");
assertThrows(IllegalArgumentException.class, closureContainingCodeToTest, "a message");
}
#2
23
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)
public static
T assertThrows(Class expectedType,Executable executable) Asserts that execution of the supplied executable throws an exception of the expectedType and returns the exception.
断言所提供的可执行文件的执行会引发expectedType的异常并返回异常。
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.
如果您不想对异常实例执行其他检查,只需忽略返回值。
@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 Executable
in org.junit.jupiter.api
.
该方法将使用org.junit.jupiter.api中的Functional Interface Executable。
Refer :
参考:
- http://junit.org/junit5/docs/current/user-guide/#writing-tests-assertions
- 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-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-
- 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-
#3
8
They've changed it in JUnit 5 (expected: InvalidArgumentException, actual: invoked method) and code looks like this one:
他们在JUnit 5中更改了它(预期:InvalidArgumentException,actual:invoked method),代码如下所示:
@Test
public void wrongInput() {
Throwable exception = assertThrows(InvalidArgumentException.class,
()->{objectName.yourMethod("WRONG");} );
}
#4
7
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
ExpectGeneralException.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
ExpectCustomException.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());
}
#5
5
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 ArrayList
will throw a NoSuchElementException
. assertThrows
declares the expected exception and provides a lambda supplier (takes no arguments and returns a value).
在包含空ArrayList的可选项上调用get()将抛出NoSuchElementException。 assertThrows声明预期的异常并提供lambda供应商(不接受任何参数并返回值)。
Thanks to @prime for his answer which I hopefully elaborated on.
感谢@prime的回答,我希望能够详细阐述。
#6
2
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());
}
#7
1
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(
#1
74
You can use assertThrows()
, which allows you to test multiple exceptions within the same test. With support for lambdas in Java 8, this is probably going to become the canonical way to test for exceptions in JUnit.
您可以使用assertThrows(),它允许您在同一测试中测试多个异常。在Java 8中支持lambdas,这可能会成为在JUnit中测试异常的规范方法。
Per the JUnit docs:
根据JUnit文档:
import static org.junit.jupiter.api.Assertions.assertThrows;
...
@Test
void exceptionTesting() {
Executable closureContainingCodeToTest = () -> throw new IllegalArgumentException("a message");
assertThrows(IllegalArgumentException.class, closureContainingCodeToTest, "a message");
}
#2
23
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)
public static
T assertThrows(Class expectedType,Executable executable) Asserts that execution of the supplied executable throws an exception of the expectedType and returns the exception.
断言所提供的可执行文件的执行会引发expectedType的异常并返回异常。
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.
如果您不想对异常实例执行其他检查,只需忽略返回值。
@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 Executable
in org.junit.jupiter.api
.
该方法将使用org.junit.jupiter.api中的Functional Interface Executable。
Refer :
参考:
- http://junit.org/junit5/docs/current/user-guide/#writing-tests-assertions
- 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-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-
- 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-
#3
8
They've changed it in JUnit 5 (expected: InvalidArgumentException, actual: invoked method) and code looks like this one:
他们在JUnit 5中更改了它(预期:InvalidArgumentException,actual:invoked method),代码如下所示:
@Test
public void wrongInput() {
Throwable exception = assertThrows(InvalidArgumentException.class,
()->{objectName.yourMethod("WRONG");} );
}
#4
7
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
ExpectGeneralException.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
ExpectCustomException.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());
}
#5
5
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 ArrayList
will throw a NoSuchElementException
. assertThrows
declares the expected exception and provides a lambda supplier (takes no arguments and returns a value).
在包含空ArrayList的可选项上调用get()将抛出NoSuchElementException。 assertThrows声明预期的异常并提供lambda供应商(不接受任何参数并返回值)。
Thanks to @prime for his answer which I hopefully elaborated on.
感谢@prime的回答,我希望能够详细阐述。
#6
2
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());
}
#7
1
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(