我有以下方法,我希望验证行为
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() ));
...
}
Run Code Online (Sandbox Code Playgroud)
在我的@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));
Run Code Online (Sandbox Code Playgroud)
但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
);
Run Code Online (Sandbox Code Playgroud)
我怎么能告诉Mockito检查这两个值?
Bra*_*rad 96
进一步阅读使我尝试使用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"));
Run Code Online (Sandbox Code Playgroud)
Chr*_*sch 55
如果两个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));
Run Code Online (Sandbox Code Playgroud)
Joh*_*n B 23
尝试这样的事情:
verify(errors, times(2))
.add(AdditionalMatchers.or(eq("exception.message"), eq("exception.detail")),
any(ActionError.class));
Run Code Online (Sandbox Code Playgroud)
Bri*_*ice 16
你的代码可能有问题.因为事实上你实际上写了这段代码:
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());
Run Code Online (Sandbox Code Playgroud)
请注意,就实际调用而言,第一次验证甚至不是有序的.
另外,我建议你实际上不要模拟你不拥有的类型,例如struts类型.
[编辑@Brad]
在我的IDE中运行Brice的代码(上面)后,我可以看到我使用了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));
Run Code Online (Sandbox Code Playgroud)
epo*_*pox 11
=1= 告诉 Mokito 总的呼叫期望。
=2= 告诉 Mokito 每个参数组合预期出现多少次。(如果times被省略,Mokito 假设times(1))。
verify(errors, times(2)).add(any(), any(ActionMessage.class));
verify(errors).add(eq("exception.message"), any());
verify(errors).add(eq("exception.detail"), any());
Run Code Online (Sandbox Code Playgroud)
OP码正确;它会检查你需要什么。
您的问题出在您的 Prod 代码中,该代码(似乎)从未使用ActionError arg 类型调用第一个 arg 组合。所以 Mokito 的抱怨是正确的。然而(我同意)投诉信息对于多次通话来说是令人困惑的。
解决方案:确保(首先)您确实精确地调用了该方法两次(使用任何参数)。
sen*_*982 10
您可以使用Mockito.atLeastOnce()
哪个允许Mockito传递测试,即使该mockObject将被多次调用.
Mockito.verify(mockObject, Mockito.atLeastOnce()).testMethod(Mockito.eq(1));
Mockito.verify(mockObject, Mockito.atLeastOnce()).testMethod(Mockito.eq(2));
Run Code Online (Sandbox Code Playgroud)