Mockito 从2.1.0后开始支持对final类型的mock,默认是未开启的,如果需要开启支持,需要在test的resource目录下新建mockito-extensions文件夹,并且在里面放一个名为org.mockito.plugins.MockMaker的文件,文件内容是mock-maker-inline。那么Mockitor是怎么实现对final类型的mock的呢?我们来看下官方提示的

https://static.javadoc.io/org.mockito/mockito-core/2.11.0/org/mockito/Mockito.html#39

Mockito 2.1.0 Mock Fianl类的原理

之前的话,直接mock final类型会提示:

org.mockito.exceptions.base.MockitoException:
Cannot mock/spy class com.mockito.xxxClass
Mockito cannot mock/spy because :
 - final class

因为mockito做了校验。

mockito.mock静态方法,调用了MockitoCore类的mock方法,

Mockito 2.1.0 Mock Fianl类的原理

MockSettingsImpl

Mockito 2.1.0 Mock Fianl类的原理

MockUtil

Mockito 2.1.0 Mock Fianl类的原理

SubclassByteBuddyMockMaker

Mockito 2.1.0 Mock Fianl类的原理

然后如果启用了final支持后,通过这个类InlineByteBuddyMockMaker来实现isTypeMockable方法。只有

Mockito 2.1.0 Mock Fianl类的原理

转而把final类型的部分去掉了,同时不支持原始类型的包装类

Mockito 2.1.0 Mock Fianl类的原理

如果通过了校验,同样采用objenesis来创建类的实例

Mockito 2.1.0 Mock Fianl类的原理

Instantiator采用的是ObjenesisInstantiator来实现的,如果是构造器,则用ConstructorInstantiator。

至于启用的文件及文件内容是由PluginRegistry定义加载的

Mockito 2.1.0 Mock Fianl类的原理

定义的INLINE_ALIAS

Mockito 2.1.0 Mock Fianl类的原理

loadPlugin读取路径的文件

Mockito 2.1.0 Mock Fianl类的原理

正常类路径不存在插件时返回ByteBuddyMockMaker,否则返回自定义的。

Mockito 2.1.0 Mock Fianl类的原理


总结一下就是,通过加载值得自定义的MockMaker来跳过校验,然后利用Objenesis来生成动态代理对象

相关文章: