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.