Как проверить несколько вызовов методов с разными параметрами - PullRequest
93 голосов
/ 14 декабря 2011

У меня есть следующий метод, который я хочу проверить поведение на

public void methodToTest( Exception e, ActionErrors errors ) {

    ...
        errors.add( "exception.message", 
                    ActionMessageFactory.createErrorMessage(e.toString() ));

        errors.add( "exception.detail",
                    ActionMessageFactory.createErrorMessage(e.getStackTrace()[0].toString() ));

    ...
}

В моем классе @Test я надеялся сделать что-то подобное, чтобы убедиться, что errors.add() вызывается с "exception.message" и снова с "exception.detail"

verify(errors).add(eq("exception.message"), any(ActionError.class));
verify(errors).add(eq("exception.detail"), any(ActionError.class));

однако Mockito жалуется следующим образом

Argument(s) are different! Wanted:
actionErrors.add(
    "exception.message",
    <any>
);

Actual invocation has different arguments:
actionErrors.add(
    "exception.detail",
    org.apache.struts.action.ActionError@38063806
);

Как я могу сказать Mockito проверить оба значения?

Ответы [ 6 ]

94 голосов
/ 14 декабря 2011

Дальнейшее чтение побудило меня попробовать использовать ArgumentCaptors и следующие работы, хотя гораздо более многословно, чем хотелось бы.

ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);

verify(errors, atLeastOnce()).add(argument.capture(), any(ActionMessage.class));

List<String> values = argument.getAllValues();

assertTrue(values.contains("exception.message"));
assertTrue(values.contains("exception.detail"));
49 голосов
/ 10 декабря 2015

Если уместен порядок обоих вызовов add(), вы можете использовать InOrder:

InOrder inOrder = inOrder(errors, errors);
inOrder.verify(errors).add(eq("exception.message"), any(ActionError.class));
inOrder.verify(errors).add(eq("exception.detail"), any(ActionError.class));
22 голосов
/ 14 декабря 2011

Попробуйте что-то вроде этого:

verify(errors, times(2))
     .add(AdditionalMatchers.or(eq("exception.message"), eq("exception.detail")),
          any(ActionError.class));
16 голосов
/ 14 декабря 2011

у вас, вероятно, есть проблема в вашем коде. Потому что на самом деле вы пишете этот код:

Map<Character, String> map = mock(Map.class);

map.put('a', "a");
map.put('b', "b");
map.put('c', "c");

verify(map).put(eq('c'), anyString());
verify(map).put(eq('a'), anyString());
verify(map).put(eq('b'), anyString());

Обратите внимание, что первая проверка не соответствует порядку действительных вызовов.

Кроме того, я бы порекомендовал вам не издеваться над типами, которыми вы не владеете, например типом стояков.

[EDIT @Brad]

После выполнения кода Бриса (выше) в моей IDE я вижу, что я использовал ActionError вместо ActionMessage, поэтому мой verify () не соответствовал. Сообщение об ошибке, которое я первоначально отправил, вводило меня в заблуждение, заставляя меня думать, что это был первый не соответствующий аргумент. Оказывается, это был второй аргумент.

Итак, ответ на мой вопрос

/** 
 * note that ActionMessageFactory.createErrorMessage() returns ActionMessage
 * and ActionError extends ActionMessage
 */
verify(errors).add(eq("exception.message"), any(ActionMessage.class));
verify(errors).add(eq("exception.detail"), any(ActionMessage.class));
8 голосов
/ 05 сентября 2017

Вы можете использовать Mockito.atLeastOnce(), что позволяет Mockito пройти тест, даже если этот mockObject будет вызываться много раз.

Mockito.verify(mockObject, Mockito.atLeastOnce()).testMethod(Mockito.eq(1));

Mockito.verify(mockObject, Mockito.atLeastOnce()).testMethod(Mockito.eq(2));
0 голосов
/ 28 мая 2019

По аналогии с @ sendon1928 мы можем использовать:

Mockito.times(wantedInvocationCount)

чтобы убедиться, что метод вызывался точное количество раз (на мой взгляд, предпочтительное решение). После этого мы можем позвонить

Mockito.verifyNoMoreInteractions(mock)

Чтобы убедиться, что макет не использовался дальше ни в каком контексте. Полный пример:

Mockito.verify(mockObject, Mockito.times(wantedInvocationCount)).testMethod(Mockito.eq(1));

Mockito.verify(mockObject, Mockito.times(wantedInvocationCount)).testMethod(Mockito.eq(2));

Mockito.verifyNoMoreInteractions(mockObject)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...