첫 번째 호출은 실패하고 두 번째 호출은 성공하는 시뮬레이션


119

Mockito를 사용하여 아래의 (단순화 된) 코드를 테스트하고 싶습니다. 나는 Mockito에게 처음에는 실패하고 두 번째는 성공하라고 말하는 방법을 모릅니다.

for(int i = 1; i < 3; i++) {
  String ret = myMock.doTheCall();

  if("Success".equals(ret)) {
    log.write("success");
  } else if ( i < 3 ) {
    log.write("failed, but I'll try again. attempt: " + i);
  } else {
    throw new FailedThreeTimesException();
  }
}

다음을 사용하여 성공 테스트를 설정할 수 있습니다.

Mockito.when(myMock).doTheCall().thenReturn("Success");

그리고 실패 테스트 :

Mockito.when(myMock).doTheCall().thenReturn("you failed");

그러나 한 번 (또는 두 번) 실패하면 성공하는지 어떻게 테스트 할 수 있습니까?

답변:


250

에서 워드 프로세서 :

때로는 동일한 메서드 호출에 대해 다른 반환 값 / 예외로 스텁이 필요합니다. 일반적인 사용 사례는 반복자를 조롱하는 것입니다. Mockito의 원래 버전에는 단순한 조롱을 촉진하기위한이 기능이 없었습니다. 예를 들어 반복자 대신 Iterable 또는 단순히 컬렉션을 사용할 수 있습니다. 이는 자연스러운 스터 빙 방법을 제공합니다 (예 : 실제 컬렉션 사용). 드문 경우에 연속 호출을 스터 빙하는 것이 유용 할 수 있습니다.

when(mock.someMethod("some arg"))
   .thenThrow(new RuntimeException())
  .thenReturn("foo");

//First call: throws runtime exception:
mock.someMethod("some arg");

//Second call: prints "foo"
System.out.println(mock.someMethod("some arg"));

따라서 귀하의 경우에는 다음을 원할 것입니다.

when(myMock.doTheCall())
   .thenReturn("You failed")
   .thenReturn("Success");

25
이것은 void 메소드를 다루는 내 시나리오에 대한 올바른 방향 (감사)을 가리 켰습니다.이 경우에는 대체 스타일을 사용해야합니다 ...doThrow(new RuntimeException()).doNothing().when(myMock).doTheCall();
haggisandchips

38

원하는 것을 쓰는 가장 짧은 방법은

when(myMock.doTheCall()).thenReturn("Success", "you failed");

이와 thenReturn같이 여러 개의 인수를 제공하면 필요한만큼 여러 번 사용되는 가장 마지막 인수를 제외하고 각 인수는 최대 한 번만 사용됩니다. 예를 들어,이 경우 네 번 전화를 걸면 "성공", "실패", "실패", "실패"가 표시됩니다.


22

이와 관련된 댓글은 읽기 어렵 기 때문에 형식화 된 답변을 추가하겠습니다.

void예외를 발생 시키는 함수를 사용 하여이 작업을 수행 한 다음 동작 없음 단계를 수행하려는 경우 다음과 같은 작업을 수행합니다.

Mockito.doThrow(new Exception("MESSAGE"))
            .doNothing()
            .when(mockService).method(eq());

4

에 추가하려면 대답, 당신은 또한 체인에 조롱 전화를 루프를 사용할 수 있습니다. 이것은 같은 것을 여러 번 조롱하거나 어떤 패턴으로 조롱해야 할 때 유용합니다.

예 (파 페치 된 것임에도 불구하고) :

import org.mockito.stubbing.Stubber;

Stubber stubber = doThrow(new Exception("Exception!"));
for (int i=0; i<10; i++) {
    if (i%2 == 0) {
        stubber.doNothing();
    } else {
        stubber.doThrow(new Exception("Exception"));
    }
}
stubber.when(myMockObject).someMethod(anyString());

나는 실제로이 Stubber에 대해 몰랐고 유용하다는 것을 알게되었습니다. +1.
Mihai Morcov

void 메서드를 호출해야하는 경우 이것이 정답이어야합니다.
db80

4

상황이 다르기 void때문에 첫 번째 호출에 대한 함수 를 모의 하고 두 번째 호출에서 정상적으로 실행하고 싶었습니다 .

이것은 나를 위해 작동합니다.

Mockito.doThrow(new RuntimeException("random runtime exception"))
       .doCallRealMethod()
       .when(spy).someMethod(Mockito.any());
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.