升级Mockito 5后Junit 4中@Inject注入Mock失效问题排查
问题原因及解决方案
你的问题出在Mockito 5的两处关键变更:
- 默认Mock Answer从
ReturnsSmartNulls改为了ReturnsEmptyValues,String类型方法的默认返回值从null变成了空字符串; - 默认启用了
mock-maker-inline作为Mock实现方式,对类的Mock行为和之前的CGLIB模式有所不同。
最终导致你在@Before中配置的Stub没有生效,请求触发方法时返回了默认的空字符串。
解决方法
1. 更换Stub写法(推荐)
把when(xxx).thenReturn()的写法换成doReturn().when(),避免提前执行目标方法导致的Stub绑定问题:
@Before public void before() { // ... 其他代码 doReturn("Included due to excludes overridden property").when(exclOverriddenCtrlMock).foo(); }
when(exclOverriddenCtrlMock.foo())会先执行一次foo()方法,Mockito 5的inline模式下这次调用可能干扰后续的Stub逻辑;而doReturn不会执行目标方法,直接完成Stub绑定,能确保请求触发时返回你指定的内容。
2. 验证Mock实例一致性
确认Spring注入测试类的exclOverriddenCtrlMock和处理请求的控制器是同一个实例:
- 在
@Before中打印exclOverriddenCtrlMock.hashCode(); - 在测试方法中添加
verify(exclOverriddenCtrlMock).foo(),验证方法确实被调用过。
如果验证失败,说明Spring可能创建了额外的代理类,需要调整配置确保Mock实例被正确用作控制器。
3. 临时恢复旧版默认行为(可选)
如果需要暂时沿用Mockito 4的默认Answer,可以在创建Mock时显式指定:
@Bean public ExcludesOverriddenControllerImpl getExcludesOverriddenControllerImpl() { return mock(ExcludesOverriddenControllerImpl.class, Mockito.RETURNS_SMART_NULLS); }
但这只是临时方案,建议优先采用第一种方法解决Stub不生效的根本问题。
内容的提问来源于stack exchange,提问作者JGleason
相关产品推荐
相关产品推荐

