Mockito 던져진 예외를 조롱하고 주장하는 방법?


답변:


75

BDD 스타일 솔루션 (Java 8로 업데이트)

Mockito 만으로는 예외 처리를위한 최상의 솔루션이 아닙니다. Catch-Exception 과 함께 Mockito 를 사용 하십시오.

모키 토 + 캐치 예외 + AssertJ

given(otherServiceMock.bar()).willThrow(new MyException());

when(() -> myService.foo());

then(caughtException()).isInstanceOf(MyException.class);

샘플 코드

의존성


2
"캐치 예외"란 무엇입니까? 링크가 있습니까?
Duncan Jones

뭐야 caughtException?
Saif Masadeh

알겠습니다com.googlecode.catchexception.CatchException.caughtException;
Saif Masadeh

212

두 번째 질문에 먼저 답하십시오. JUnit 4를 사용하는 경우 테스트에 주석을 달 수 있습니다

@Test(expected=MyException.class)

예외가 발생했다고 주장합니다. 그리고 mockito로 예외를 "모의"하려면

when(myMock.doSomething()).thenThrow(new MyException());

2
이 방법은 상태가있는 객체의 방법을 테스트 할 때 허용되지 않습니다. 예를 들어 두 번째로 호출하면 예외를 발생시키는 객체 메소드가 있습니다. 그리고 첫 번째 메서드 호출이 아닌 두 번째 메서드 호출 중에 예외가 발생하는지 테스트하기 위해 테스트해야합니다. 첫 번째 메소드 호출 (준비 단계에서) 중에 MyException이 발생하면 테스트에 실패해야합니다. 그러나이 방법을 사용하면 어떤 메소드 호출 중에 예외가 발생했는지 확인할 수 없습니다.
Sneg

이 경우 첫 번째 메소드 호출에서 예외를 포착하여 RuntimeException으로 랩핑 할 수 있습니다.
Sneg

29

예외 메시지도 테스트하려면 Mockito와 함께 JUnit의 ExpectedException을 사용할 수 있습니다.

@Rule
public ExpectedException expectedException = ExpectedException.none();

@Test
public void testExceptionMessage() throws Exception {
    expectedException.expect(AnyException.class);
    expectedException.expectMessage("The expected message");

    given(foo.bar()).willThrow(new AnyException("The expected message"));
}

given()어디에서 왔습니까?
Mohammad Faisal


또한 @Rule을 사용하는 것이 좋습니다.이 방법으로 예상 메시지 또는 원인 또는 예외와 관련된 기타 항목을 테스트 할 수 있기 때문입니다. 예외의 원인을 확인하기 위해 expectedException.expectCause (Mockito.sameInstance (expectedException)) 또는 expectedException.expectCause (Mockito.instanceOf (MyException.class)) 및 기타 유용한 몇 가지를 사용합니다.
Crenguta S

19

2015 년 6 월 19 일에 대한 답변이 업데이트되었습니다 (Java 8을 사용하는 경우).

그냥 assertj를 사용하십시오

assertj-core-3.0.0 + Java 8 Lambdas 사용

@Test
public void shouldThrowIllegalArgumentExceptionWhenPassingBadArg() {
assertThatThrownBy(() -> myService.sumTingWong("badArg"))
                                  .isInstanceOf(IllegalArgumentException.class);
}

참조 : http://blog.codeleak.pl/2015/04/junit-testing-exceptions-with-java-8.html


나를 위해 일했습니다 ... 또한 예외 메시지도 확인할 수 있습니다 .assertThatThrownBy (()-> myService.sumTingWong ( "badArg")). hasMessage ( "test") .isInstanceOf (IllegalArgumentException.class);
Sritam Jagadev

17

JUnit 4 및 Mockito 1.10.x를 사용하는 경우 다음과 같이 테스트 방법에 주석을 답니다.

@Test(expected = AnyException.class)

원하는 예외 사용을 던지기 위해 :

Mockito.doThrow(new AnyException()).when(obj).callAnyMethod();

16

다음과 같이 예외가 발생하도록하십시오.

when(obj.someMethod()).thenThrow(new AnException());

테스트에서 이러한 예외가 발생한다고 주장하여 문제가 발생했는지 확인하십시오.

@Test(expected = AnException.class)

또는 일반적인 모의 검증으로 :

verify(obj).someMethod();

테스트가 중간 코드가 예외를 처리하도록 증명하도록 설계된 경우 후자의 옵션이 필요합니다 (예 : 테스트 메소드에서 예외가 발생하지 않음).


verify전화가 예외를 주장 합니까 ?
NilsH

@NilsH 아니오. 그러나 when절이 정확하다면 예외를 던져야 합니다.
Duncan Jones

10

Mockito의 doThrow를 사용 하고 원하는 예외를 포착하여 나중에 발생하도록합니다.

@Test
public void fooShouldThrowMyException() {
    // given
    val myClass = new MyClass();
    val arg = mock(MyArgument.class);
    doThrow(MyException.class).when(arg).argMethod(any());
    Exception exception = null;

    // when
    try {
        myClass.foo(arg);
    } catch (MyException t) {
        exception = t;
    }

    // then
    assertNotNull(exception);
}

5

mockito를 사용하면 예외가 발생할 수 있습니다.

when(testingClassObj.testSomeMethod).thenThrow(new CustomException());

Junit5를 사용 하면 테스트 메소드 가 호출 될 때 예외가 발생 하는지 여부 주장 할 수 있습니다 .

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

여기에서 샘플을 찾으십시오. assert exception junit


감사 ! 나를 위해 일
HariKishore 7

1

mockito와 관련이 없으면 예외를 포착하고 해당 속성을 주장 할 수 있습니다. 예외가 발생했는지 확인하려면 예외를 발생시키는 명령문 다음에 try 블록 내에 false 조건을 지정하십시오.


@MariuszS 응답은 Mockito와 관련이없는 말에 올바르게 응답합니다
pringi

@pringi 감사합니다. 질문은 예외를 조롱하고 포착하는 것과 관련이 있습니다. 이것이 테스트중인 코드의 행동에 달려 있는지 궁금합니다.
eel ghEEz

1

또는 클래스 생성자에서 예외가 발생하는 경우 :

@Rule
public ExpectedException exception = ExpectedException.none();

@Test
public void myTest() {    

    exception.expect(MyException.class);
    CustomClass myClass= mock(CustomClass.class);
    doThrow(new MyException("constructor failed")).when(myClass);  

}

-1

예외 메시지로 확인 :

    try {
        MyAgent.getNameByNode("d");
    } catch (Exception e) {
        Assert.assertEquals("Failed to fetch data.", e.getMessage());
    }

이와 같이 작성하면 예외가 발생 하지 않아도 테스트는 계속 통과 합니다. 우리가 처음에 피하고 싶은 것은
Christian Lim
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.