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

为何Lenient能解决Mockito测试中的不必要Stubbing异常?

问题本质与原理拆解

1. 「Unnecessary Stubbing」异常的触发原因

Mockito默认开启**Strict Stubbing(严格存根)**机制,核心是帮你清理无效测试代码——如果你给某个方法做了stub配置,但整个测试过程中这个方法根本没被调用,Mockito就会抛出这个异常,提醒你测试逻辑可能存在错误。

放到你的场景里:

  • 业务类CityServiceImpl依赖的是**静态单例CityMapper.INSTANCE**来执行对象转换
  • 你在测试类里@Mock出来的是一个全新的CityMapper实例,stub的是这个Mock实例的cityToCityDto方法
  • 但业务代码全程都没用到你Mock的这个实例,始终调用的是静态的CityMapper.INSTANCE,所以你配置的stub完全没被执行,Mockito的严格检查就触发了异常。

2. lenient.when()或Lenient注解的作用

Lenient模式本质是关闭Strict Stubbing的严格检查,它允许测试中存在未被调用的stub配置,不会因为有没用到的stub就抛出异常。

直白点说,用了lenient之后,Mockito就不再追究你这个没被用到的stub了,自然就不会报错。但要注意:这只是解决了表面的报错,你的测试逻辑其实有问题——你stub的对象根本没被业务代码使用,这个stub本身是无效的,测试中执行的还是真实CityMapper.INSTANCE的转换逻辑,而非你Mock的行为。

补充:正确的测试姿势

如果你的目标是Mock掉CityMapper的转换逻辑,应该从根源上替换业务类的依赖:

  • 把CityMapper.INSTANCE改成可注入的依赖,比如通过构造函数注入CityMapper,测试时直接把Mock实例传入业务类
  • 若必须保留静态单例,可使用PowerMock等工具Mock静态实例(不推荐,静态依赖会增加测试复杂度)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 01:20:38