[java] 다른 매개 변수로 여러 메서드 호출을 확인하는 방법

다음과 같은 방법으로 동작을 확인하고 싶습니다.

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에게 두 값을 모두 확인하도록하려면 어떻게해야합니까?



답변

추가 읽기를 통해 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"));


답변

add()호출 의 순서 가 관련이있는 경우 다음을 사용할 수 있습니다 InOrder.

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


답변

다음과 같이 시도하십시오.

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


답변

코드에 문제가있을 수 있습니다. 사실이 코드를 실제로 작성하기 때문입니다.

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

첫 번째 확인은 실제 호출과 관련하여 순서가 동일하지 않습니다.

또한 소유하지 않은 유형, 예를 들어 struts 유형을 실제로 조롱하지 않는 것이 좋습니다.

[@Brad 수정]

IDE에서 Brice의 코드 (위)를 실행 한 후 ActionMessage 대신 ActionError를 사용했음을 알 수 있으므로 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));


답변

Mockito.atLeastOnce()mockObject가 여러 번 호출 되더라도 Mockito가 테스트를 통과하도록 허용 하는 것을 사용할 수 있습니다 .

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

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


답변

1) Mokito에게 총 예상 통화량을 알려줍니다.

2) 각 매개 변수 조합이 예상되는 횟수를 Mokito에게 알립니다.

verify(errors, times(2)).add(any(), any(ActionMessage.class));

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


답변

@ 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)