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.