【问题标题】:mockito how to verify using methodname and reflectionmockito 如何使用方法名和反射进行验证
【发布时间】:2015-08-25 15:07:00
【问题描述】:

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

我想做这样的事情:

  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() 效果很好

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

问候

【问题讨论】:

  • 这完全是对语法的滥用,但meth.invoke(Mockito.verify(mockObject)) 有效吗?
  • 感谢这个想法不幸的是,它什么也没做:我之前可以调用或不调用 getGuid 方法,但该行似乎没有任何效果
  • meth.invoke(Mockito.verify(mockObject)) 会更正确,就像 Mockito.verify(meth.invoke(mockObject));您传递的不是模拟对象,而是执行结果。虽然我不能让它工作,以太......
  • 确保您从 PowerMock 或 Mockito 获取 Class 对象。只需使用 SimpleObj.class,它就会看到该方法是最终的,并且不会返回对存根的引用。

标签: reflection mockito powermock verify powermockito


【解决方案1】:

这适用于我使用常规 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);
}

【讨论】:

    【解决方案2】:

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

    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 );
    }
    

    【讨论】:

      猜你喜欢
      • 2017-06-17
      • 1970-01-01
      • 1970-01-01
      • 2017-07-01
      • 2013-01-31
      • 1970-01-01
      • 2022-01-14
      • 1970-01-01
      • 2011-09-04
      相关资源
      最近更新 更多