有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何为基元类型创建Mockito ArgumentCaptor?

我试图使用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()));
  }
}

结果,当我试图捕获传递给服务器的值时,我在测试中得到了NullPointerException。下一步移动呼叫

我已经检查过了,那个俘虏不是空的。 如果我更改服务器的参数类型。下一步从int移动到Integer,然后一切正常

我还没有找到任何方法来创建类似“InArgumentCaptor”的东西(比如为matchers创建的anyInt

有没有办法,让测试工作,没有服务器。下一步移动到整数


共 (1) 个答案

  1. # 1 楼答案

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

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

    ^{}中:

    /**
     * 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是final,Server.nextMove是final,或者上述任何一个都是受保护的或包私有的(因为Mockito的某些版本在Java编译器创建的合成方法中遇到了问题,从而使这些方法工作)

    如果您可以看到ArgumentCaptor.capture()在不应该返回的地方返回null(与上面的代码相反),那么这听起来像是一个Mockito bug