JUnit 5 : 예외를 선언하는 방법은 무엇입니까?


214

JUnit 5에서 메소드가 예외를 처리한다고 주장하는 더 좋은 방법이 있습니까?

현재 테스트에서 예외가 발생하는지 확인하기 위해 @Rule을 사용해야하지만 테스트에서 여러 메소드가 예외를 throw 할 것으로 예상되는 경우에는 작동하지 않습니다.


1
예외를 확인하기 위해 AssertJ를 확인하는 것이 좋습니다. JUnit5보다 유연합니다.
user1075613

답변:


323

를 사용 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"));
}

11
구식 학교에서 "Junit5에 대해 많이 알지 못하고 Java8에 대해서는 충분하지 않을 것"이라고 생각합니다. 이것은 다소 기묘 해 보입니다. 좀 더 설명을 추가해 주시겠습니까? "테스트중인 실제 '제작 코드'가있는 부분은 ... 던져야 할 것"과 같은 것입니까?
GhostCat

1
() -> 0 개의 인수를 허용하는 람다 식을 가리 킵니다 . 따라서 예외를 발생시킬 것으로 예상되는 "생산 코드"는 지정된 코드 블록 (즉, throw new...중괄호 안의 명령문)에 있습니다.
Sam Brannen

1
일반적으로 람다 식은 피험자 (SUT)와 상호 작용합니다. 다시 말해, 위와 같이 예외를 직접 던지는 것은 단지 설명을위한 것입니다.
Sam Brannen

1
expectThrows가 더 이상 사용되지 않는 것 같습니다. 문서에서는 지금 assertThrows ()를 사용한다고 말합니다.
depsypher

5
버전 5.0.0-M4 부터 expectThrows 는 더 이상 사용할 수 없습니다. assertThrows 만 허용됩니다. 참조 github.com/junit-team/junit5/blob/master/documentation/src/docs/... : '제거되지 Assertions.expectThrows을 () 메소드를 Assertions.assertThrows 찬성 ()
gil.fernandes

91

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.

참조 :


1
이것으로 정상에! 이것은 JUnit 5에서 가장 최신의 가장 좋은 답변입니다. 또한 IntelliJ는 Lambda에 한 줄만 있으면 람다를 더 많이 압축합니다.assertThrows(NoSuchElementException.class, myLinkedList::getFirst);
anon58192932

26

그들은 JUnit 5에서 그것을 변경했으며 (예상 : InvalidArgumentException, actual : invoked 메소드) 코드는 다음과 같습니다.

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

21

이제 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());
}

1
JUnit이 내장 예외와 사용자 정의 예외를 처리하는 방법에는 차이가 없습니다.
raindev

9

나는 이것이 더 간단한 예라고 생각한다.

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

get()비어있는 ArrayList것을 포함하는 옵션을 호출 하면가 발생합니다 NoSuchElementException. assertThrows예상되는 예외를 선언하고 람다 공급자를 제공합니다 (인수를 취하지 않고 값을 반환 함).

내가 잘 설명 한 그의 답변에 대한 @prime에게 감사드립니다.


1
이 메소드 assertThrows는 발생 된 예외를 리턴합니다. 따라서 NoSuchElementException e = assertThrows(NoSuchElementException.class, () -> opt2.get());아래에서 와 같이 원하는 예외 개체에 대한 모든 종류의 어설 션을 수행 할 수 있습니다.
캡틴 맨

8

사용할 수 있습니다 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());
}

2

더 간단한 하나의 라이너. 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()
}

1

실제로이 특정 예제의 설명서에 오류가 있다고 생각합니다. 의도 된 방법은 expectThrows입니다.

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

3
"Assertions.assertThrows ()에 찬성하여 더 이상 사용되지 않는 Assertions.expectThrows () 메소드를 제거했습니다."
Martin Schröder

Junit 5의 경우, org.testng.Assert가 아닌 org.junit.jupiter.api.Assertions에 있는지 확인하십시오. 우리 프로젝트에는 Junit과 TestNG가 모두 포함되어 있으며 assertExpects로 변경할 때까지 assertThrows에서 void 오류를 반환합니다. 내가 org.testng.Assert를 사용하고있는 것으로 나타났습니다.
barryku

-5

쉬운 방법이 있습니다.

@Test
void exceptionTest() {

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

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

}

예상 예외가 발생했을 때만 성공합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.