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

2022-09-02 00:54:33

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

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

我模拟了其他测试的验证器类,但对于这个,我需要模拟对cartarItemsFilter对象的更改,我不知道该怎么做。


答案 1

答案是肯定的,你可以,根据测试的需要,基本上有两个层次。

如果您只想测试与模拟对象的交互,则只需使用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();

答案 2

为了补充Kevin Welker的答案,如果你的MyClass是一个自定义类,那么在其中定义一个等于/哈希码方法,以便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));

推荐