为何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
相关产品推荐
相关产品推荐

