Обратные звонки с Mockito

java testing mockito

33887 просмотра

4 ответа

У меня есть код

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

Как я могу с помощью Mockito захватить объект обратного вызова и вызвать callback.reply (x)

Автор: Kurru Источник Размещён: 12.11.2019 09:25

Ответы (4)


73 плюса

Вы хотите настроить Answerобъект, который делает это. Ознакомьтесь с документацией Mockito по адресу https://static.javadoc.io/org.mockito/mockito-core/2.8.47/org/mockito/Mockito.html#answer_stubs.

Вы могли бы написать что-то вроде

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конечно, заменить на то, что должно быть)

Автор: Dawood says reinstate Monica Размещён: 28.11.2012 11:56

49 плюса

Подумайте об использовании ArgumentCaptor , который в любом случае ближе подходит к «захватить [bing] объект обратного вызова».

/**
 * 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 */);
}

Хотя это Answerхорошая идея, когда обратный вызов должен немедленно вернуться (читай: синхронно), он также вводит накладные расходы на создание анонимного внутреннего класса и небезопасное приведение элементов invocation.getArguments()[n]к нужному типу данных. Также требуется, чтобы вы делали какие-либо утверждения о состоянии системы перед обратным вызовом из ОТВЕТА в ответ, что означает, что ваш ответ может увеличиваться в размере и объеме.

Вместо этого обработайте ваш обратный вызов асинхронно: захватите объект обратного вызова, переданный вашей службе, с помощью ArgumentCaptor. Теперь вы можете делать все свои утверждения на уровне тестового метода и вызывать их по своему усмотрению reply. Это особенно полезно, если ваша служба отвечает за множественные одновременные обратные вызовы, потому что у вас больше контроля над порядком возврата обратных вызовов.

Автор: Jeff Bowman Размещён: 29.11.2012 04:04

6 плюса

Если у вас есть такой метод:

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

Я надеюсь, что это может кому-то помочь, так как я потратил много времени на выяснение этого решения

Автор: Sumit Kumar Saha Размещён: 06.08.2018 06:11

3 плюса

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*/);
    }
});
Автор: Garrett Hall Размещён: 29.11.2012 12:00
Вопросы из категории :
32x32