Mockito when()调用如何工作? [英] How does mockito when() invocation work?

查看:883
本文介绍了Mockito when()调用如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出以下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:

  1. Mockito.mock代表 org.mockito.internal.MockitoCore .模拟,将默认的模拟设置作为参数传递.
  2. MockitoCore.mock代表 org.mockito.internal.util.MockUtil .createMock
  3. MockUtil类使用ClassPathLoader类来获取MockMaker的实例,以用于创建模拟.默认情况下,使用 CgLibMockMaker 类. /li>
  4. CgLibMockMaker使用从JMock借用的类, ClassImposterizer 处理创建模拟.所使用的'mockito magic'的关键部分是用于创建模拟的MethodInterceptor:mockito MethodInterceptorFilter,以及一系列MockHandler实例,包括MockHandlerImpl .方法拦截器将调用传递给MockHandlerImpl实例,该实例实现在对模拟调用方法时(即搜索是否已记录答案,确定调用是否代表新的存根等)应应用的业务逻辑.默认状态是,如果尚未为正在调用的方法注册存根,则将返回类型合适的 empty 值.
  1. Mockito.mock delegates to org.mockito.internal.MockitoCore.mock, passing the default mock settings as a parameter.
  2. MockitoCore.mock delegates to org.mockito.internal.util.MockUtil.createMock
  3. The MockUtil class uses the ClassPathLoader class to get an instance of MockMaker to use to create the mock. By default, the CgLibMockMaker class is used.
  4. CgLibMockMaker uses a class borrowed from JMock, ClassImposterizer that handles creating the mock. The key pieces of the 'mockito magic' used are the MethodInterceptor used to create the mock: the mockito MethodInterceptorFilter, 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:

  1. mock.method()
  2. when(<result of step 1>)
  3. <result of step 2>.thenReturn
  1. mock.method()
  2. when(<result of step 1>)
  3. <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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆