You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mockito中verify对Mock生效但对Spy不生效的问题排查

关于Mockito Spy无法捕获Mock对象方法调用的问题分析

问题重现

验证失败的代码

var list = (ArrayList<String>) Mockito.mock(ArrayList.class);
var spyList = Mockito.spy(list);

list.add("test");
Mockito.verify(spyList).add("test"); // 此处验证失败

验证成功的代码

var list = (ArrayList<String>) Mockito.mock(ArrayList.class);
//var spyList = Mockito.spy(list);

list.add("test");
Mockito.verify(list).add("test"); // 此处验证成功

原因分析

  • Spy与原Mock是完全独立的代理对象:Mockito的Spy本质是对目标对象的包装代理,但它和原对象(这里是Mock出来的list)是两个分离的实例。你调用list.add("test")是直接操作原Mock,Spy没有介入这个调用流程,自然不会记录该调用行为,verify时就会失败。
  • Spy的核心逻辑是拦截自身方法调用:不管目标是真实对象还是Mock对象,只有当你调用Spy实例的方法时,Spy才会拦截并记录调用。你现在绕开了Spy直接操作原对象,相当于Spy全程“没看见”这个调用。

正确写法示例

场景1:Spy真实对象(你原本的需求)

// 直接Spy真实的ArrayList实例
var realList = new ArrayList<String>();
var spyList = Mockito.spy(realList);

// 必须调用Spy对象的方法,而非原真实对象的方法
spyList.add("test");
Mockito.verify(spyList).add("test"); // 验证通过

场景2:Spy Mock对象(仅作演示,实际无业务意义)

如果一定要Spy一个Mock对象并让验证通过,需要调用Spy的方法:

var list = Mockito.mock(ArrayList.class);
var spyList = Mockito.spy(list);

// 调用Spy的add方法,而非原Mock的方法
spyList.add("test");
Mockito.verify(spyList).add("test"); // 验证通过

补充说明

直接verify原Mock能成功,是因为原Mock本身会记录自己的方法调用行为,你调用的是它的方法,自然能被verify捕获。而Spy和它没有任何调用关联,所以无法感知到原Mock的操作。

内容的提问来源于stack exchange,提问作者Toralf Schneider

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 20:37:49