Development Tip

Mockito로 콜백 호출

yourdevel 2020. 12. 7. 20:59
반응형

Mockito로 콜백 호출


코드가 있습니다

service.doAction(request, Callback<Response> callback);

Mockito를 사용하여 콜백 객체를 잡고 callback.reply (x)를 호출하는 방법


Answer이를 수행 하는 개체 를 설정하려고 합니다. https://static.javadoc.io/org.mockito/mockito-core/2.8.47/org/mockito/Mockito.html#answer_stubs 에서 Mockito 문서를 살펴보십시오.

다음과 같이 쓸 수 있습니다.

when(mockService.doAction(any(Request.class), any(Callback.class))).thenAnswer(
    new Answer<Object>() {
        Object answer(InvocationOnMock invocation) {
            ((Callback<Response>) invocation.getArguments()[1]).reply(x);
            return null;
        }
});

( x물론 그게되어야하는 것으로 대체 )


ArgumentCaptor를 사용하는 것이 좋습니다. 어떤 경우 든 "콜백 객체를 잡아라"와 더 가깝게 일치합니다.

/**
 * Captor for Response callbacks. Populated by MockitoAnnotations.initMocks().
 * You can also use ArgumentCaptor.forClass(Callback.class) but you'd have to
 * cast it due to the type parameter.
 */
@Captor ArgumentCaptor<Callback<Response>> callbackCaptor;

@Test public void testDoAction() {
  // Cause service.doAction to be called

  // Now call callback. ArgumentCaptor.capture() works like a matcher.
  verify(service).doAction(eq(request), callbackCaptor.capture());

  assertTrue(/* some assertion about the state before the callback is called */);

  // Once you're satisfied, trigger the reply on callbackCaptor.getValue().
  callbackCaptor.getValue().reply(x);

  assertTrue(/* some assertion about the state after the callback is called */);
}

an Answer은 콜백이 즉시 반환되어야하는 경우 (동 기적으로 읽기) 좋은 생각 이지만 익명의 내부 클래스 invocation.getArguments()[n]를 만들고 원하는 데이터 유형으로 요소를 안전하지 않게 캐스팅하는 오버 헤드도 발생합니다 . 또한 WITHIN the Answer에서 시스템의 사전 콜백 상태에 대한 주장을해야합니다. 이는 답변의 크기와 범위가 커질 수 있음을 의미합니다.

대신 콜백을 비동기 적으로 처리하십시오. ArgumentCaptor를 사용하여 서비스에 전달 된 콜백 객체를 캡처하십시오. 이제 테스트 메서드 수준에서 모든 어설 션을 만들고 reply선택할 때 호출 할 수 있습니다. 콜백이 반환되는 순서를 더 잘 제어 할 수 있으므로 서비스가 여러 동시 콜백을 담당하는 경우 특히 유용합니다.


다음과 같은 방법이있는 경우 :-

public void registerListener(final IListener listener) {
    container.registerListener(new IListener() {
        @Override
        public void beforeCompletion() {
        }

        @Override
        public void afterCompletion(boolean succeeded) {
            listener.afterCompletion(succeeded);
        }
    });
}

그런 다음 위의 방법을 쉽게 모의 할 수 있습니다.

@Mock private IListener listener;

@Test
public void test_registerListener() {
    target.registerListener(listener);

    ArgumentCaptor<IListener> listenerCaptor =
            ArgumentCaptor.forClass(IListener.class);

    verify(container).registerListener(listenerCaptor.capture());

    listenerCaptor.getValue().afterCompletion(true);

    verify(listener).afterCompletion(true);
}

이 솔루션을 찾는 데 많은 시간을 보냈으므로 이것이 누군가에게 도움이되기를 바랍니다.


when(service.doAction(any(Request.class), any(Callback.class))).thenAnswer(
    new Answer() {
    Object answer(InvocationOnMock invocation) {
        Callback<Response> callback =
                     (Callback<Response>) invocation.getArguments()[1];
        callback.reply(/*response*/);
    }
});

참고 URL : https://stackoverflow.com/questions/13616547/calling-callbacks-with-mockito

반응형