PowerMock(Mockito):如何测试私有方法并mock其内部公共服务与私有方法
私有方法嵌套调用场景的测试解决方案
以下方案基于Java技术栈,使用PowerMock + Mockito测试框架实现你提出的三个测试目标。
前置依赖
需要引入对应测试依赖,以Maven为例:
<!-- Mockito核心依赖 --> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>3.4.6</version> <scope>test</scope> </dependency> <!-- PowerMock核心依赖 --> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> <version>2.0.7</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito2</artifactId> <version>2.0.7</version> <scope>test</scope> </dependency>
注意PowerMock与Mockito版本需要匹配,可参考官方版本对应关系调整
测试实现步骤
1. 测试类基础配置
在测试类上添加PowerMock专属注解,开启私有方法测试支持:
@RunWith(PowerMockRunner.class) // 这里填包含私有方法的目标类全类名 @PrepareForTest({TargetClass.class}) public class TargetClassTest { // 要测试的目标类实例,用@InjectMocks自动注入依赖 @InjectMocks private TargetClass targetClass; // 公共Service依赖,用@Mock生成mock实例 @Mock private Service service; }
2. 实现三个测试目标
- 目标1:调用目标私有方法
nameMethod
使用PowerMock提供的Whitebox.invokeMethod反射工具直接调用私有方法,无需修改原方法访问权限// 传入目标类实例、方法名、入参即可调用 String result = Whitebox.invokeMethod(targetClass, "nameMethod", "参数1", "参数2"); - 目标2:Mock公共Service的
getValues方法
用Mockito原生API即可完成mock,和普通公共方法mock逻辑一致:// 自定义mock返回值 when(service.getValues(anyString())).thenReturn("mock出来的返回值"); - 目标3:校验内部私有方法
checkString是否被调用
使用PowerMock的verifyPrivate工具验证私有方法调用次数、入参:// 验证checkString方法被调用1次,且入参符合预期 PowerMockito.verifyPrivate(targetClass, Mockito.times(1)) .invoke("checkString", anyString(), anyString());
完整测试用例示例
@Test public void testNameMethod() throws Exception { // 1. mock公共service方法 when(service.getValues(anyString())).thenReturn("testValue"); // 2. 调用目标私有方法 Whitebox.invokeMethod(targetClass, "nameMethod", "param1", "param2"); // 3. 校验内部私有方法是否被调用 PowerMockito.verifyPrivate(targetClass, Mockito.times(1)) .invoke("checkString", eq("预期第一个入参"), eq("预期第二个入参")); }
注意事项
- 测试私有方法属于测试坏味道,仅建议临时调试使用,长期来看建议重构代码:可将
checkString方法抽为独立工具类方法或调整为包访问权限,降低测试复杂度 - 若使用JUnit5,PowerMock兼容性较差,可使用
mockito-inline依赖配合JDK原生反射工具实现私有方法调用与校验
内容的提问来源于stack exchange,提问作者Mikeybuuuu
相关产品推荐
相关产品推荐

