Java 如何模拟影响对象的void返回方法

Java 如何模拟影响对象的void返回方法,java,mockito,Java,Mockito,我正在为我的应用程序编写单元测试,我想知道Mockito框架是否可能影响传递到返回模拟类void的方法中的对象。例如,调用一个模拟验证类,该类包含一个返回void但通过作为参数传入的对象跟踪各种更改和元数据的方法 public GetCartItemsOutput getCartItems(GetCartItemsInput getCartItemsInput) { CartItemsFilter cartItemsFilter = new CartItemsFilter();

我正在为我的应用程序编写单元测试,我想知道Mockito框架是否可能影响传递到返回模拟类void的方法中的对象。例如,调用一个模拟验证类,该类包含一个返回void但通过作为参数传入的对象跟踪各种更改和元数据的方法

public GetCartItemsOutput getCartItems(GetCartItemsInput getCartItemsInput) {
    CartItemsFilter cartItemsFilter = new CartItemsFilter();
    validator.validateCartItemsInput(getCartItemsInput, cartItemsFilter); ...

我在其他测试中模拟了validator类,但在这次测试中,我需要模拟对cartItemsFilter对象的更改,我不知道该怎么做。

答案是可以的,根据测试的需要,基本上有两个级别

如果您只想测试与模拟对象的交互,您可以简单地使用该方法来验证是否调用了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();

ArgumentCaptor也可能会有所帮助

以下是从中找到的片段:

ArgumentCaptor argument=ArgumentCaptor.forClass(GetCartItemsInput.class);
验证(mock).getCartItems(argument.capture());
assertEquals(cartItemsFilter,argument.getValue());

要补充凯文·韦尔克的答案, 如果您的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));

这并不能解决op的问题,他需要回答谢谢你的帮助。我花了一段时间思考“((MyClass)args[0]).myClassSetMyField(NEW_VALUE);”,但最终我发现关键是设置传入模拟方法的参数。再说一遍,泰。
 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));