JUnit 5에서 메소드가 예외를 처리한다고 주장하는 더 좋은 방법이 있습니까?
현재 테스트에서 예외가 발생하는지 확인하기 위해 @Rule을 사용해야하지만 테스트에서 여러 메소드가 예외를 throw 할 것으로 예상되는 경우에는 작동하지 않습니다.
JUnit 5에서 메소드가 예외를 처리한다고 주장하는 더 좋은 방법이 있습니까?
현재 테스트에서 예외가 발생하는지 확인하기 위해 @Rule을 사용해야하지만 테스트에서 여러 메소드가 예외를 throw 할 것으로 예상되는 경우에는 작동하지 않습니다.
답변:
를 사용 assertThrows()
하면 동일한 테스트 내에서 여러 예외를 테스트 할 수 있습니다. Java 8에서 람다를 지원하므로 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().contains("Stuff"));
}
() ->
0 개의 인수를 허용하는 람다 식을 가리 킵니다 . 따라서 예외를 발생시킬 것으로 예상되는 "생산 코드"는 지정된 코드 블록 (즉, throw new...
중괄호 안의 명령문)에 있습니다.
Java 8 및 JUnit 5 (Jupiter)에서는 다음과 같이 예외를 주장 할 수 있습니다. 사용org.junit.jupiter.api.Assertions.assertThrows
공개 정적 <T 확장 가능 Throwable> T assertThrows (Class <T> expectType, 실행 파일 실행 가능)
제공된 실행 파일을 실행하면 expectType의 예외가 발생하고 예외를 반환합니다.
예외가 발생하지 않거나 다른 유형의 예외가 발생하면이 메소드는 실패합니다.
예외 인스턴스에서 추가 점검을 수행하지 않으려면 리턴 값을 무시하십시오.
@Test
public void itShouldThrowNullPointerExceptionWhenBlahBlah() {
assertThrows(NullPointerException.class,
()->{
//do whatever you want to do here
//ex : objectName.thisMethodShoulThrowNullPointerExceptionForNullParameter(null);
});
}
이 방법은의 기능 인터페이스 Executable
를 사용합니다 org.junit.jupiter.api
.
참조 :
assertThrows(NoSuchElementException.class, myLinkedList::getFirst);
이제 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을 테스트 할 샘플을 찾을 수 있습니다. assert exception code sample
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());
}
나는 이것이 더 간단한 예라고 생각한다.
List<String> emptyList = new ArrayList<>();
Optional<String> opt2 = emptyList.stream().findFirst();
assertThrows(NoSuchElementException.class, () -> opt2.get());
get()
비어있는 ArrayList
것을 포함하는 옵션을 호출 하면가 발생합니다 NoSuchElementException
. assertThrows
예상되는 예외를 선언하고 람다 공급자를 제공합니다 (인수를 취하지 않고 값을 반환 함).
내가 잘 설명 한 그의 답변에 대한 @prime에게 감사드립니다.
assertThrows
는 발생 된 예외를 리턴합니다. 따라서 NoSuchElementException e = assertThrows(NoSuchElementException.class, () -> opt2.get());
아래에서 와 같이 원하는 예외 개체에 대한 모든 종류의 어설 션을 수행 할 수 있습니다.
사용할 수 있습니다 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());
}
더 간단한 하나의 라이너. Java 8 및 JUnit 5를 사용하는이 예제에는 람다 식 또는 중괄호가 필요하지 않습니다.
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(