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
之前的话,直接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方法,
MockSettingsImpl
MockUtil
SubclassByteBuddyMockMaker
然后如果启用了final支持后,通过这个类InlineByteBuddyMockMaker来实现isTypeMockable方法。只有
转而把final类型的部分去掉了,同时不支持原始类型的包装类
如果通过了校验,同样采用objenesis来创建类的实例
Instantiator采用的是ObjenesisInstantiator来实现的,如果是构造器,则用ConstructorInstantiator。
至于启用的文件及文件内容是由PluginRegistry定义加载的
定义的INLINE_ALIAS
loadPlugin读取路径的文件
正常类路径不存在插件时返回ByteBuddyMockMaker,否则返回自定义的。
总结一下就是,通过加载值得自定义的MockMaker来跳过校验,然后利用Objenesis来生成动态代理对象