21

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

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

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

4

3 回答 3

37

答案是肯定的,你可以,根据你的测试需要,基本上有两个级别的这样做。

如果您只想测试与模拟对象的交互,您可以简单地使用该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();
于 2012-09-14T17:42:14.190 回答
5

添加到 Kevin Welker 的答案中,如果您的 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));
于 2016-01-15T06:10:11.440 回答
-1

ArgumentCaptor 也可能有所帮助。

这是从这里找到的一个片段:

  ArgumentCaptor<GetCartItemsInput > argument = ArgumentCaptor.forClass(GetCartItemsInput .class);
  verify(mock).getCartItems(argument.capture());
  assertEquals(cartItemsFilter, argument.getValue());
于 2012-09-16T07:17:05.387 回答