Testing Callbacks with Mockito

Dev.Hammy·2024년 4월 1일

Mockito_Tutorial

목록 보기
11/21

1. Overview

이 짧은 튜토리얼에서는 인기 있는 테스트 프레임워크인 Mockito를 사용하여 콜백을 테스트하는 방법에 중점을 둘 것입니다.

먼저 ArgumentCaptor를 사용한 다음 직관적인 doAnswer() 메서드를 사용하는 두 가지 솔루션을 살펴보겠습니다.

Mockito로 테스트하는 방법에 대해 자세히 알아보려면 여기에서 Mockito 시리즈를 확인하세요.

2. Introduction to Callbacks

콜백은 주어진 시간에 인수를 콜백(실행)할 것으로 예상되는 메서드에 인수로 전달되는 코드 조각입니다.

이 실행은 동기 콜백처럼 즉시 실행될 수도 있지만 일반적으로 비동기 콜백처럼 나중에 발생할 수도 있습니다.

콜백 사용에 대한 일반적인 시나리오는 서비스 호출의 응답을 처리해야 하는 서비스 상호 작용 중에입니다. 이 튜토리얼에서는 아래에 표시된 Service 인터페이스를 테스트 사례의 협력자로 사용합니다.

public interface Service {
    void doAction(String request, Callback<Response> callback);
}

Calllback 인수에서는 reply(T response) 메소드를 사용하여 응답을 처리할 클래스를 전달합니다.

public interface Callback<T> {
    void reply(T response);
}

2.1 A Simple Service

또한 간단한 서비스 예제를 사용하여 콜백을 전달하고 호출하는 방법을 보여드리겠습니다.

public void doAction() {
    service.doAction("our-request", new Callback<Response>() {
        @Override
        public void reply(Response response) {
            handleResponse(response);
        }
    });
}

handlerResponse 메소드는 Response 객체에 일부 데이터를 추가하기 전에 응답이 유효한지 확인합니다.

private void handleResponse(Response response) {
    if (response.isValid()) {
        response.setData(new Data("Successful data response"));
    }
}

명확성을 위해 Java Lamda 표현식을 사용하지 않기로 선택했지만 service.doAction 호출을 더 간결하게 작성할 수도 있습니다.

service.doAction("our-request", response -> handleResponse(response));

3. Using an ArgumentCaptor

이제 Mockito를 사용하여 ArgumentCaptor를 사용하여 Callback 개체를 가져오는 방법을 살펴보겠습니다.

@Test
public void givenServiceWithValidResponse_whenCallbackReceived_thenProcessed() {
    ActionHandler handler = new ActionHandler(service);
    handler.doAction();

    verify(service).doAction(anyString(), callbackCaptor.capture());

    Callback<Response> callback = callbackCaptor.getValue();
    Response response = new Response();
    callback.reply(response);

    String expectedMessage = "Successful data response";
    Data data = response.getData();
    assertEquals(
      "Should receive a successful message: ", 
      expectedMessage, data.getMessage());
}

이 예에서는 이 핸들러의 doAction 메소드를 호출하기 전에 먼저 ActionHandler를 생성합니다. 이는 콜백을 호출하는 Simple Service doAction 메소드 호출에 대한 단순한 래퍼입니다.

다음으로 첫 번째 인수로 anyString()을 전달하고 Callback 객체를 캡처하는 두 번째 인수로 callbackCaptor.capture()를 전달하는 모의 서비스 인스턴스에서 doAction이 호출되었는지 확인합니다. 그런 다음 getValue() 메서드를 사용하여 인수의 캡처된 값을 반환할 수 있습니다.

이제 Callback 개체가 있으므로 reply 메서드를 직접 호출하고 Response 데이터에 올바른 값이 있는지 assert하기 전에 기본적으로 유효한 응답 개체를 만듭니다.

4. Using doAnswer() Method

이제 Mockito의 Answer 개체와 doAnswer 메서드를 사용하여 void 메서드 doAction을 스텁하는 콜백이 있는 스텁 메서드에 대한 일반적인 솔루션을 살펴보겠습니다.

@Test
public void givenServiceWithInvalidResponse_whenCallbackReceived_thenNotProcessed() {
    Response response = new Response();
    response.setIsValid(false);

    doAnswer((Answer<Void>) invocation -> {
        Callback<Response> callback = invocation.getArgument(1);
        callback.reply(response);

        Data data = response.getData();
        assertNull("No data in invalid response: ", data);
        return null;
    }).when(service)
        .doAction(anyString(), any(Callback.class));

    ActionHandler handler = new ActionHandler(service);
    handler.doAction();
}

그리고 두 번째 예에서는 먼저 나중에 테스트에서 사용할 잘못된 Response 개체를 만듭니다.

다음으로 doAction이 호출될 때 호출을 가로채고 invocation.getArgument(1)을 사용하여 메서드 인수를 가져오도록 모의 서비스에 Answer를 설정하여 Callback 인수를 가져옵니다.

마지막 단계는 ActionHandler를 생성하고 Answer가 호출되도록 하는 doAction을 호출하는 것입니다.

stubbing void 메서드에 대해 자세히 알아보려면 여기를 참조하세요.

0개의 댓글