我知道我真的不需要知道 Mockito 在幕后如何做所有事情才能使用它,但这已经让我困惑了一段时间,所以我更想了解它。有几种 Mockito 方法我无法理解它们是如何工作的。一个很好的例子是:
OngoingStubbing<T> Mockito.when(T methodCall)
您可以使用它来执行以下操作:
Object mockedObject = Mockito.mock(Object.class);
Mockito.when(mockedObject.toString()).thenReturn("super cool string");
System.out.println(mockedObject.toString());
此代码将给出输出:
super cool string
我知道如何使用它,但我不明白它是如何工作的。 Mockito.when 如何知道我们关心的模拟对象和方法是什么?据我所知,我们没有传入mockedObject,而是传入mockedObject.toString(),它是一个String类型的值。我非常确定在设置所有“when/thenReturn”内容之前,mockedObject.toString() 仅返回 null。那么为什么这与这样做不一样:
Object mockedObject = Mockito.mock(Object.class);
mockedObject.toString();
Mockito.when(null).thenReturn("super cool string");
System.out.println(mockedObject.toString());
显然第二个代码段没有任何意义,但看起来这两个代码段在功能上应该是等效的。
编辑: 这两个代码段实际上是相同的。请参阅下面我对自己问题的回答。
最佳答案
哦!
我想在发布这个问题之前我应该尝试运行我的示例代码。
事实证明,这两个代码段实际上是等效的。我只是假设他们不是。
这一发现揭示了 Mockito.when 的底层实现方式。
我现在最好的猜测是,当模拟mockedObject时,新创建的Object.toString()实现的一部分会记录调用.toString()方法(无论如何都必须这样做才能获得Mockito。验证()工作)。然后,它必须在某种线程局部静态变量中记录对模拟方法的调用。然后,当我调用 when() 时,它实际上会忽略输入值(可能除了使用其类型?),然后搜索最近在该线程中存在的任何模拟对象上调用的任何模拟方法(或者可能只是与该签名匹配的方法调用)。无论最后调用的是哪个方法,它都会决定修改该方法。
这当然只是我根据我如何观察mockito功能的猜测。实际的实现可能有所不同,但这至少是有意义的。
关于java - Mockito.when 是如何在后台工作的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42496911/