如何为原始类型创建Mockito ArgumentCaptor?

时间:2017-02-02 20:58:39

标签: java mockito

我正在尝试使用Mockito来捕获“int”类型的参数。

这是我正在测试的代码:

public class Client {

  private final Board board;
  private final Server server;

  private void makeMove() {
    nextMove = 11;
    server.nextMove(nextMove);
  }

  public void moveAccepted(boolean accepted) {
    if (accepted) {
        board.updateBoard(nextMove);
    } else {
        ...
    }
  }
}

这是测试代码:

@RunWith(MockitoJUnitRunner.class)
public class ClientTest {

  private Client client;

  @Mock
  private Board mockBoard;

  @Mock
  private Server mockServer;

  @Captor
  private ArgumentCaptor<Integer> moveCaptor;

  @Test
  public void testGamePlay() {
    client.forceNextMove();
    verify(mockServer).nextMove(moveCaptor.capture()); // NPE here
    client.moveAccepted(true);
    verify(mockBoard).updateBoard(eq(moveCaptor.getValue()));
  }
}

因此,当我尝试捕获传递给 server.nextMove 调用的值时,我在测试中得到 NullPointerException

我已经检查过,捕获者不是空的。 如果我将server.nextMove的参数类型从 int 更改为 Integer ,那么一切正常。

我还没有找到任何方法来创建类似“IntArgumentCaptor”的东西(比如匹配器的 anyInt )。

有没有办法让测试工作,没有server.nextMove到整数

1 个答案:

答案 0 :(得分:3)

您使用的是哪个版本的Mockito?根据{{​​3}},您不需要做任何不同的事情。例如,这比调用any()更聪明,因为ArgumentCaptor必须通过forClass创建(通过它可以确定要返回的基本类型)或@Captor(可以读取)字段类型并适当调用forClass

public T capture() {
    Mockito.argThat(capturingMatcher);
    return defaultValue(clazz);
}

ArgumentCaptor's implementation中:

/**
 * Returns the boxed default value for a primitive or a primitive wrapper.
 *
 * @param primitiveOrWrapperType The type to lookup the default value
 * @return The boxed default values as defined in Java Language Specification,
 *         <code>null</code> if the type is neither a primitive nor a wrapper
 */
public static <T> T defaultValue(Class<T> primitiveOrWrapperType) {
    return (T) PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.get(primitiveOrWrapperType);
}

如果您的NPE来自您控制的代码,那么这是一个重要标志:它表示Mockito在调用verify期间推迟了您的实施,这可能表明Server.nextMove无法撤销。如果Server是最终的,Server.nextMove是最终的,或者上述任何一个是受保护的或包私有的(因为某些版本的Mockito在使用Java编译器将创建的合成方法时遇到问题),可能会发生这种情况。做那些工作)。

如果你可以看到ArgumentCaptor.capture()返回null的时间不应该(与上面的代码相反),那么这听起来像是一个Mockito错误。