Mockito的thenReturn在内部方法调用失效的解决方法
核心原因
when(mockedClass.brokenMethod(...)).thenReturn(...)存根语法的执行逻辑是先真实调用一次被Mock的方法,再完成存根绑定。如果被Mock的方法本身存在Bug会抛出异常,存根流程会直接中断,无法注册你指定的返回值。
你提供的示例代码还存在注入逻辑错误:手动创建的Mock实例没有注入到待测试类中,待测试类实际调用的是Spring上下文里的真实带Bug实例,也会导致存根不生效。
修复方案
- 替换存根语法:使用不会触发真实方法调用的
doReturn().when()链式写法,直接给Mock对象注册返回规则,完全绕开被Mock方法本身的Bug逻辑,不会执行原方法的任何代码。 - 修正Mock对象注入逻辑:通过注解将Mock实例自动注入到Spring测试上下文,替换掉待测试类依赖的真实实例,保证待测试方法调用的是你配置过存根的Mock对象。
正确代码示例
@SpringBootTest public class TestClass { private final String idString = "idString"; // 将Spring容器中对应类型的实例替换为Mock对象,自动注入到所有依赖它的Bean中 @MockBean private T mockedClass; // 注入待测试类,其内部依赖的mockedClass已经被替换为Mock实例 @Autowired private ClassToBeTested classToBeTested; @Test public void test() { Arg1 arg1 = new Arg1(...); ReturnData expectedReturn = new ReturnData(...); // 自定义的SUCCESS状态返回值 // 存根配置:匹配到对应方法调用时直接返回预期值,不执行原brokenMethod的逻辑 doReturn(expectedReturn).when(mockedClass).brokenMethod(arg1, idString); // 调用待测试方法,内部调用brokenMethod时会直接返回预期值,不会触发原方法Bug T response = classToBeTested.testedMethod(); // 后续执行断言逻辑即可 } }
注意事项
如果存根不生效,优先检查参数匹配逻辑:如果待测试方法内部传入
brokenMethod的参数和你写在存根里的参数不满足equals判断,存根就不会触发。如果不需要严格校验参数,可以用Mockito参数匹配器简化配置,比如doReturn(expectedReturn).when(mockedClass).brokenMethod(any(Arg1.class), eq(idString)),只要参数类型匹配、第二个参数值等于idString就会返回预期值。
内容的提问来源于stack exchange,提问作者src2012
相关产品推荐
相关产品推荐

