developer tip

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

optionbox 2020. 8. 25. 07:55
반응형

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


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

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

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

Also, I would recommand you to actually don't mock types you don't own, eg the struts type.

[EDIT @Brad]

After running Brice's code (above) in my IDE I can see that I have used ActionError instead of ActionMessage, so that is why my verify() was not matching. The error message I initially posted was misleading me into thinking it was the first argument that was not matching. It turns out it was the second argument.

So the answer to my question is

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

You can use Mockito.atLeastOnce() which allows Mockito to pass the test even if that mockObject will be called many times.

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

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

In a simmilar way to @sendon1928 we can use:

Mockito.times(wantedInvocationCount)

to make sure method was called exact number of times (preferable solution in my opinion). Afterwards, we can call

Mockito.verifyNoMoreInteractions(mock)

To make sure that mock was not used further in any context. Full example:

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

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

Mockito.verifyNoMoreInteractions(mockObject)

참고URL : https://stackoverflow.com/questions/8504074/how-to-verify-multiple-method-calls-with-different-params

반응형