8

我有一个对象的间谍或模拟对象,我想验证一个方法是否被调用问题,我在执行时间而不是编译时间收到方法名

我想做类似的事情:

  SimpleObj mockObject= Mockito.mock(SimpleObj.class);
  Class myClass = SimpleObj.class;
  Method meth = myClass.getMethod("getGuid");

  Mockito.verify(meth.invoke(mockObject));

我已经使用了一种解决方法

MockingDetails mockingDetails = Mockito.mockingDetails(mockObject);

Collection<Invocation> invocations = mockingDetails.getInvocations();

List<String> methodsCalled = new ArrayList<>();
for (Invocation anInvocation : invocations) {
  methodsCalled.add(anInvocation.getMethod().getName());
}
assertTrue(methodsCalled.contains("getGuid");

问题在我使用 PowerMockito 之前它有效:对于标准方法它有效,但如果该方法是最终的,则该方法不存在mockingDetails.getInvocations() (但即使在mockingDetails.getInvocations() 实际verify(mock).getGuid()作品中没有以一种好的方式存在

所以如果你有任何想法/建议会很高兴

问候

4

2 回答 2

2

这对我使用常规的 Mockito 有效(我用它来验证 android.bluetooth.BluetoothGatt 中的隐藏方法“refresh()”是否被调用:

private void assertMethodInvoked(@NonNull Object object,
                                 @NonNull String methodName,
                                 @NonNull VerificationMode verificationMode) throws Exception {
    final Method method = object.getClass().getDeclaredMethod(methodName);
    final Object verify = verify(object, verificationMode);
    method.invoke(verify);
}
于 2019-12-04T09:57:02.337 回答
0

我实际上使用反射完成了这项工作......我无法使用匹配器,但我有原始参数。我的测试验证了中间代理和数据转换过程调用了真正的实现:

private void assertMethodExecuted(String testName, Object ...params) throws Exception {
    assertManagerMethodExecuted(getMethodName(testName), params);
}

private void assertManagerMethodExecuted(String methodName, Object[] params) throws Exception {
    MiGRPCManagerImpl manager = Whitebox.getInternalState(server, MiGRPCManagerImpl.class);
    Method method = Arrays.stream(manager.getClass().getMethods())
        .filter(each -> each.getName().equals(methodName))
        .findFirst()
        .orElse(null);
    MiGRPCManagerImpl verify = Mockito.verify(manager, new VerificationMode() {

        @Override
        public void verify(VerificationData data) {
            assertEquals(1, data.getAllInvocations().size());
            data.getAllInvocations().get(0).getMethod().equals(method);
        }

        @Override
        public VerificationMode description(String description) {
            return this;
        }
    });

    if (params.length == 0) {
        method.invoke(verify);
    } else if (params.length == 1) {
        method.invoke(verify, params[0]);
    } else {
        method.invoke(verify, params);
    }

}

private String getMethodName(String testName) {
    return testName.substring(testName.indexOf("_") + 1, testName.length());
}

一个测试是这样的:

@Test
public void test_disconnectFromGui() throws SecurityException, Exception {
    String ip = factory.newInstance(String.class);
    String userName = factory.newInstance(String.class);
    fixture.disconnectFromGui(userName, ip );
    assertMethodExecuted(new Object() {}.getClass().getEnclosingMethod().getName(), userName, ip );
}
于 2019-02-05T14:47:28.820 回答