Mockito.spy()如何在保留原类型的同时实现监视功能?
Mockito spy() 的监视实现原理
你观察到的现象很关键:Mockito spy出来的对象和原对象类型完全一致,这是因为它没有用子类包装,而是直接通过字节码增强修改了目标类的逻辑。
具体实现逻辑如下:
- 字节码动态修改:Mockito依赖ASM字节码操作库,在运行时直接修改目标类(比如这里的ArrayList)的字节码。它会在每个方法的执行前后插入额外的监听代码——负责记录调用次数、参数,或者执行你预设的stub逻辑。
- 类型不变的原因:这种修改是在原类的字节码基础上进行的,并没有生成新的子类,所以调用
getClass()返回的还是原类型,但此时的类已经是被修改过的版本。 - 调用感知的方式:当你调用spy对象的方法时,首先会触发注入的监听逻辑,完成Mockito的监视任务(比如记录调用),之后才会执行原对象的真实方法逻辑(除非你用
when(spyList.add(...)).thenReturn(false)这类语法替换了原逻辑)。
你还可以做个额外验证:打印两个对象的类加载器,会发现原ArrayList实例的类加载器是系统类加载器,而spy出来的实例所属类的加载器是Mockito专用的类加载器,这也能佐证字节码被动态修改过。
内容的提问来源于stack exchange,提问作者Géza
相关产品推荐
相关产品推荐

