Mockito when()调用如何工作? [英] How does mockito when() invocation work?
问题描述
给出以下Mockito语句:
Given the following Mockito statement:
when(mock.method()).thenReturn(someValue);
鉴于ockock.method()语句会将返回值传递给when(),Mockito如何为代理创建某种东西的代理?我想这会使用一些CGLib的东西,但是有兴趣知道这在技术上是如何完成的.
How does Mockito go about creating a proxying something for a mock, given that the mock.method() statement will pass the return value to when()? I imagine that this uses some CGLib stuff, but would be interested to know how this is technically done.
推荐答案
简短的答案是,在您的示例中,mock.method()
的结果将是类型合适的空值; Mockito通过代理,方法拦截和MockingProgress
类的共享实例使用间接方式,以确定对模拟程序的方法调用是用于存根还是重放现有的存根行为,而不是通过传递有关存根的信息.模拟方法的返回值.
The short answer is that in your example, the result of mock.method()
will be a type-appropriate empty value; mockito uses indirection via proxying, method interception, and a shared instance of the MockingProgress
class in order to determine whether an invocation of a method on a mock is for stubbing or replay of an existing stubbed behavior rather than passing information about stubbing via the return value of a mocked method.
几分钟后,对微型代码进行一次微型分析,如下所示.注意,这是一个非常粗糙的描述-这里有很多细节.我建议您亲自检查 github上的资源.
A mini-analysis in a couple of minutes looking at the mockito code is as follows. Note, this is a very rough description - there are a lot of details in play here. I suggest that you check out the source on github yourself.
首先,当您使用Mockito
类的mock
方法模拟一个类时,实际上是这样:
First, when you mock a class using the mock
method of the Mockito
class, this is essentially what happens:
-
Mockito.mock
代表org.mockito.internal.MockitoCore
.模拟,将默认的模拟设置作为参数传递. -
MockitoCore.mock
代表org.mockito.internal.util.MockUtil
.createMock -
MockUtil
类使用ClassPathLoader
类来获取MockMaker
的实例,以用于创建模拟.默认情况下,使用 CgLibMockMaker 类. /li> -
CgLibMockMaker
使用从JMock借用的类,ClassImposterizer
处理创建模拟.所使用的'mockito magic'的关键部分是用于创建模拟的MethodInterceptor
:mockitoMethodInterceptorFilter
,以及一系列MockHandler实例,包括MockHandlerImpl .方法拦截器将调用传递给MockHandlerImpl实例,该实例实现在对模拟调用方法时(即搜索是否已记录答案,确定调用是否代表新的存根等)应应用的业务逻辑.默认状态是,如果尚未为正在调用的方法注册存根,则将返回类型合适的 empty 值.
Mockito.mock
delegates toorg.mockito.internal.MockitoCore
.mock, passing the default mock settings as a parameter.MockitoCore.mock
delegates toorg.mockito.internal.util.MockUtil
.createMock- The
MockUtil
class uses theClassPathLoader
class to get an instance ofMockMaker
to use to create the mock. By default, the CgLibMockMaker class is used. CgLibMockMaker
uses a class borrowed from JMock,ClassImposterizer
that handles creating the mock. The key pieces of the 'mockito magic' used are theMethodInterceptor
used to create the mock: the mockitoMethodInterceptorFilter
, and a chain of MockHandler instances, including an instance of MockHandlerImpl. The method interceptor passes invocations to MockHandlerImpl instance, which implements the business logic that should be applied when a method is invoked on a mock (ie, searching to see if an answer is recorded already, determining if the invocation represents a new stub, etc. The default state is that if a stub is not already registered for the method being invoked, a type-appropriate empty value is returned.
现在,让我们看一下示例中的代码:
Now, let's look at the code in your example:
when(mock.method()).thenReturn(someValue)
以下是此代码执行的顺序:
Here is the order that this code will execute in:
-
mock.method()
-
when(<result of step 1>)
-
<result of step 2>.thenReturn
mock.method()
when(<result of step 1>)
<result of step 2>.thenReturn
了解发生了什么的关键是当调用模拟方法上的方法时会发生什么:向方法拦截器传递有关方法调用的信息,并将其委托给其MockHandler
实例链,最终将这些实例委托给MockHandlerImpl#handle
.在MockHandlerImpl#handle
期间,模拟处理程序将创建OngoingStubbingImpl
的实例,并将其传递到共享的MockingProgress
实例.
The key to understanding what is going on is what happens when the method on the mock is invoked: the method interceptor is passed information about the method invocation, and delegates to its chain of MockHandler
instances, which eventually delegate to MockHandlerImpl#handle
. During MockHandlerImpl#handle
, the mock handler creates an instance of OngoingStubbingImpl
and passes it to the shared MockingProgress
instance.
在调用method()
之后调用when
方法时,它委托给MockitoCore.when
,后者调用
When the when
method is invoked after the invocation of method()
, it delegates to MockitoCore.when
, which calls the stub()
method of the same class. This method unpacks the ongoing stubbing from the shared MockingProgress
instance that the mocked method()
invocation wrote into, and returns it. Then thenReturn
method is then called on the OngoingStubbing
instance.
这篇关于Mockito when()调用如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!