Mockito:是否可以将mock与方法名称结合起来在when()调用中创建methodCall?

2024-03-10

我在 StackOverflow 上的第一个问题。我希望能够做类似的事情:

SomeClass 模拟 = 模拟(SomeClass.class);

String 方法名 = "someMethod";或 方法 方法 = ...someMethod...

这两件事(模拟和方法)将结合起来执行以下操作:

当(mock.someMethod()).thenReturn(null);

当然,“null”值将根据我的需要进行相应更改,但我试图确定两件事:

1)是否有可能做类似的事情this在Java中?This= 将一个类对象和一个方法组合成一个methodCall。

2)我该怎么做这样的事情?

我对此进行了无休止的研究,但找不到任何东西。问题是,即使这适用于常规类和常规方法(someClass 和 someMethod 将一起执行 someClass.someMethod()),请记住,这必须适用于模拟对象在when()调用中使用。

回答:when(method.invoke(mock)).thenReturn("Hello world.");是正确的语法,并且反射确实在 when() 调用中起作用。谢谢凯文·韦尔克!


由于您基本上要求我重新发布我的评论,并根据您的回复进行修改,作为答案,这里是:

尝试使用反射,如下所示:

when(method.invoke(mock)).thenReturn("Hello world.");

不过,我不确定这对你有什么用,因为你不能模拟/间谍类Method(这是最终的)。莫基托的when()仅适用于模拟或间谍。如果这确实对您有用,您可以发布更多细节吗?

如果它不起作用,你可以 - 正如我在 OP 的评论中建议的那样 - 走 CGLib 路线并绕过 Mockito。这实际上并不像乍看起来那么困难。在我的OSS项目中Funcito http://funcito.googlecode.com (not一个模拟框架),我剥离了很多 Mockito CGLib 代理代码并根据我的需要重写了它。它为代理类和拦截方法调用的世界提供了更简单的视图。

对评论的补充回应我明白这对你来说是如何工作的,但我不确定你是否真的理解它是如何工作的。这可能很重要的原因是,Mockito 本身工作方式的未来变化可能会导致您的解决方案在未来崩溃。从本质上讲,它起作用的原因几乎是偶然的,但它确实会起作用。

那样的方式when()应该起作用的是,括号之间发生的是对先前创建的 Mockito 生成的模拟或间谍的方法调用,这只是类的奇特代理,而不是类的真实实例。代理具有特殊的逻辑,可以拦截伪造的代理方法调用,并将其添加到已注册的代理方法调用列表中(它存储在称为IOngoingStubbing或类似的东西)供以后使用。由于 Java 在调用方法之前评估参数,这保证了代理方法调用在调用方法之前被注册/记住。when()方法实际被执行。什么是when()所做的就是从这个 OngoingStubbing 中弹出,然后它成为其上的对象thenReturns()叫做。

您没有“正确”使用它,但它仍然对您有用。如何?好吧,需要发生的只是需要调用代理上的方法才能在代理中注册IOngoingStubbing before when()被处决。你不是directly调用代理上的方法,但您通过将代理传递给来间接调用代理上的方法Method.invoke()。因此满足标准,并且when()已经有一个代理方法调用注册在IOngoingStubbing.

您可以在下面的代码中看到同样的“意外”快乐,在您意识到 Mockito 的工作原理之前,这些代码乍一看似乎毫无意义:

@Test
public void testSomething() throws Exception {
    List listMock = mock(List.class);
    Method m = List.class.getDeclaredMethod("get", int.class);
    m.invoke(listMock, Mockito.anyInt());

    when(null).thenReturn("Hello World");  // Huh? passing null?

    assertEquals("Hello World", listMock.get(0)); // works!
}

上面的测试确实通过了!尽管争论when为 null,重要的是代理(即模拟)实例在调用之前调用了正确的方法when被调用的语句。

虽然 Mockito 不太可能改变底层工作的基本方式,但它仍然有可能在未来的某个时候给你带来麻烦。就像我说的,它的成功或多或少是一个令人高兴的意外。只要您了解其运作方式以及所涉及的风险,您就会拥有更多力量。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Mockito:是否可以将mock与方法名称结合起来在when()调用中创建methodCall? 的相关文章

随机推荐