我正在为我的应用程序编写单元测试,我想知道 Mockito 框架是否有可能影响传递给返回 void 模拟类的方法的对象。例如,调用一个模拟验证类,该类包含一个返回 void 的方法,但通过作为参数传入的对象跟踪各种更改和元数据。.
public GetCartItemsOutput getCartItems(GetCartItemsInput getCartItemsInput) {
CartItemsFilter cartItemsFilter = new CartItemsFilter();
validator.validateCartItemsInput(getCartItemsInput, cartItemsFilter); ...
我为我的其他测试模拟了验证器类,但对于这个测试,我需要模拟对 cartItemsFilter 对象的更改,我不知道该怎么做。
答案是肯定的,你可以,根据你的测试需要,基本上有两个级别。
如果只想测试与模拟对象的交互,则只需使用 verify()
方法来验证是否调用了 void 方法。
如果你的测试确实需要模拟对象来修改传递给它的参数,你将需要实现一个Answer
:
已编辑以显示使用带有 void 方法的答案的正确形式
doAnswer(new Answer() {
@Override
Object answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
((MyClass)args[0]).myClassSetMyField(NEW_VALUE);
return null; // void method, so return null
}
}).when(mock).someMethod();
在Java 8+中,上述内容用lambda进行了简化:
doAnswer(invocation-> {
Object[] args = invocation.getArguments();
((MyClass)args[0]).myClassSetMyField(NEW_VALUE);
return null;
}).when(mock).someMethod();
补充一下凯文·韦尔克的答案,如果你的MyClass是一个自定义类,那么在其中定义一个equals/hashcode方法,以便Mockito可以使用它来与方法调用完全匹配。
就我而言,"MyClass"在第三方 API 中,所以我不得不使用方法"any",如下所示 -
doAnswer(new Answer() {
Object answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
((MyClass)args[0]).myClassSetMyField(NEW_VALUE);
return null; // void method, so return null
}
}).when(mock).someMethod(any(MyClass.class));
ArgumentCaptor 也可能有所帮助。
这是从这里找到的片段:
ArgumentCaptor<GetCartItemsInput > argument = ArgumentCaptor.forClass(GetCartItemsInput .class);
verify(mock).getCartItems(argument.capture());
assertEquals(cartItemsFilter, argument.getValue());