在JUnit 5中是否有更好的方法断言方法抛出异常?
目前,我必须使用@Rule来验证我的测试是否抛出异常,但这不适用于我希望多个方法在测试中抛出异常的情况。
在JUnit 5中是否有更好的方法断言方法抛出异常?
目前,我必须使用@Rule来验证我的测试是否抛出异常,但这不适用于我希望多个方法在测试中抛出异常的情况。
当前回答
您可以使用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"));
}
其他回答
您可以使用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());
}
我认为这是一个更简单的例子
List<String> emptyList = new ArrayList<>();
Optional<String> opt2 = emptyList.stream().findFirst();
assertThrows(NoSuchElementException.class, () -> opt2.get());
在包含空数组列表的可选对象上调用get()将抛出NoSuchElementException异常。assertThrows声明预期的异常并提供lambda提供者(不接受参数并返回值)。
感谢@prime的回答,我希望能详细说明。
更简单的一行代码。使用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()
}
TL;DR:如果您使用的是JUnit 5.8.0+版本,您可以使用assertThrowsExactly()而不是assertThrows()来匹配确切的异常类型。
assertThrowsExactly(FileNotFoundException.class, () -> service.blah());
您可以使用assertThrows(),但是使用assertThrows,即使抛出的异常是子类型,您的断言也将通过。
这是因为,JUnit 5通过调用Class.isInstance(..)来检查异常类型,即使抛出的异常是子类型,Class.isInstance(..)也会返回true。
解决方法是在Class上断言:
Throwable throwable = assertThrows(Throwable.class, () -> {
service.readFile("sampleFile.txt");
});
assertEquals(FileNotFoundException.class, throwable.getClass());
现在Junit5提供了一种断言异常的方法
您可以测试常规异常和定制异常
一般的异常场景:
ExpectGeneralException.java
public void validateParameters(Integer param ) {
if (param == null) {
throw new NullPointerException("Null parameters are not allowed");
}
}
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());
}
您可以在这里找到一个测试CustomException的示例:断言异常代码示例
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
@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());
}