我在试着理解Mockito的内部是如何工作的。到目前为止,代码对我来说很难理解,我正在寻找一份关于Mockito基本工作原理的高级调查。
Mockito @ GrepCode
我已经写了一些示例代码来演示我目前的理解:
class C {
String s;
public void getS() { return s; }
// ...
}
C cm = mock( C.class);
when( cm.method() ).thenReturn( "string value");据我所知,'mock‘方法只看到cm.getS()的返回值。它如何知道方法的名称(以便将其存根)?另外,它如何知道传递给该方法的参数?
mockito API方法调用一个内部对象的方法:
// org.mockito.Mockito
public static <T> OngoingStubbing<T> when(T methodCall) {
return MOCKITO_CORE.when(methodCall);
}我在几个不同的抽象、类和对象中跟踪了方法调用,但代码是如此分离,因此很难以这种方式理解。
// org.mockito.internal.MockitoCore
public <T> OngoingStubbing<T> when(T methodCall) {
mockingProgress.stubbingStarted();
return (OngoingStubbing) stub();
}因此,如果任何人了解内部原理或有讨论/博客帖子的链接,请分享:)
发布于 2013-03-29 14:31:21
(抱歉,这篇文章太长了。TL;DR: Mockito记录了幕后的方法调用。)
C cm = mock(C.class);在这一点上,您可能认为cm是C...and的一个实例,您就错了。相反,cm是proxy object Mockito写入的一个实例,它实现了C (因此可以分配给C类型的字段/变量),但是记录了您所请求的所有内容,并按照您存根的方式进行操作。
让我们编写一个模拟类manually...and,再给它一个方法,比方说int add(int a, int b),它在实际类中添加a和b。
class MockC extends C {
int returnValue;
@Override int add(int a, int b) {
return returnValue;
}
}那里!现在,无论何时调用add,它都不会将两个数字相加,而只是返回单个返回值。合乎道理。但是,如果您想要稍后验证这些调用,该怎么办?
class MockC extends C {
List<Object[]> parameterValues = new ArrayList<>();
int returnValue;
@Override int add(int a, int b) {
parameterValues.add(new Object[] { a, b });
return returnValue;
}
}因此,现在您可以检查parameterValues列表,并确保按预期调用它。
事情是这样的: Mockito使用自动生成一个,它的行为类似于MockC,将所有的交互和返回值保存在一个大的静态列表中。这个列表被称为RegisteredInvocations,每个mock的每个方法调用都是一个Invocation,而不是Object[],但思想是相同的。
要进一步了解RegisteredInvocations以及它公开的removeLast方法为什么如此重要,请阅读InvocationContainer中的代码。因为Mockito会记录每个呼叫,所以它自然会记录when中包含的交互。一旦Mockito看到when,它就删除最后记录的交互(InvocationContainerImpl.java行45),并将其用作存根的模板--从调用对象本身读取参数值。
这就解决了大部分问题,除了像eq和any这样的参数匹配器:原来这些只是kept on a fancy stack,称为ArgumentMatcherStorage。when调用checks how many matchers are on the stack:对于add示例,零匹配器告诉Mockito推断每个记录的参数是否相等,两个匹配器告诉Mockito从堆栈中弹出这些参数并使用它们。只有一个匹配器意味着Mockito不知道你想要匹配的是哪个整数,并抛出经常令人困惑的InvalidUseOfMatchersException,这就是为什么在使用匹配器时,如果你匹配任何参数,就需要匹配每个参数。
希望这能有所帮助!
编辑: This answer更详细地描述了when方法是如何工作的。
https://stackoverflow.com/questions/15693283
复制相似问题