Java测试中如何不Mock全类仅让指定私有方法调用时返回固定值
解决方案
方案1:Mockito 3.4.0+ 原生Spy打桩(推荐,无需额外依赖)
该方案直接利用高版本Mockito的私有方法Mock能力,仅替换目标私有方法逻辑,其余方法全部走真实业务实现:
- 首先确认你的项目Mockito依赖版本≥3.4.0,版本不符合的话先升级依赖
- 按以下代码逻辑实现打桩:
import org.mockito.Mockito; import java.lang.reflect.Method; // 1. 先创建待测试类的真实实例,再生成Spy代理对象 AClassINeed realInstance = new AClassINeed(); AClassINeed spyInstance = Mockito.spy(realInstance); // 2. 反射获取报错的私有方法,有入参的话要在getDeclaredMethod第二个参数传入对应参数类型 Method failingMethod = AClassINeed.class.getDeclaredMethod("method_that_fails"); failingMethod.setAccessible(true); // 3. 打桩配置:调用该私有方法时直接返回固定值,不执行原有逻辑 // 如果方法无返回值,将doReturn换成doNothing即可 Mockito.doReturn(你需要的固定返回值) .when(spyInstance) .invoke(failingMethod); // 后续直接调用spyInstance的method_I_need_to_call即可正常测试
方案2:低版本Mockito搭配PowerMock实现
如果你的项目无法升级Mockito到3.4.0以上,可以引入PowerMock扩展实现:
- 首先引入PowerMock对应Mockito版本的依赖
- 测试类添加对应注解:
import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import org.junit.runner.RunWith; import static org.powermock.api.mockito.PowerMockito.*; @RunWith(PowerMockRunner.class) @PrepareForTest(AClassINeed.class) public class AClassINeedTest { @Test public void testMethod() throws Exception { // 1. 生成真实实例的Spy代理 AClassINeed realInstance = new AClassINeed(); AClassINeed spyInstance = spy(realInstance); // 2. 直接对私有方法打桩,PowerMock自动处理反射逻辑 // 方法有入参的话在方法名后传入对应参数匹配规则即可 doReturn(你需要的固定返回值).when(spyInstance, "method_that_fails"); // 3. 调用公有方法执行测试 spyInstance.method_I_need_to_call(); } }
注意事项
- 若目标私有方法包含入参,打桩时需要对应传入参数匹配规则,比如
Mockito.any()、Mockito.eq(指定值)等 - 两种方案均不会修改类的其他业务逻辑,完全符合你不Mock整个类、只跳过报错私有方法的需求
内容的提问来源于stack exchange,提问作者Mugen
相关产品推荐
相关产品推荐

