Mockito模拟静态类SecurityEncryption始终返回null求助
静态方法Mock异常排查(Mockito)
问题描述
对依赖两个静态类的方法做单元测试时,遇到如下问题:
- 使用Mockito的
mockStatic分别模拟SecretUtils和SecurityEncryption两个静态类 SecretUtils.getSecret()能正常返回模拟值"secreto",测试中直接调用SecurityEncryption.desencriptarString()的断言也能通过- 但在被测类
notificationSendEmailService的sendNotificationEmail()方法中,SecurityEncryption.desencriptarString()始终返回null
测试代码如下:
try(MockedStatic<SecurityEncryption> securityEncryption = mockStatic(SecurityEncryption.class); MockedStatic<SecretUtils> secretUtils = mockStatic(SecretUtils.class) ){ secretUtils.when(() -> SecretUtils.getSecret(anyString(), anyString())).thenReturn("secreto"); securityEncryption.when(() -> SecurityEncryption.desencriptarString(anyString(), anyString())).thenReturn("texto"); assertEquals("texto", SecurityEncryption.desencriptarString("", "")); notificationSendEmailService.sendNotificationEmail("", "", ""); }
被测服务使用@InjectMocks注解,且在@BeforeEach方法中调用了MockitoAnnotations.openMocks(this),不想使用PowerMockito。
排查与解决方法
1. 检查方法签名是否匹配
被测类中调用的desencriptarString可能和你Mock的方法不是同一个:
- 比如存在重载方法:你Mock的是两个
String参数的版本,但实际调用的是带其他参数类型(如CharSequence)或参数数量不同的重载方法 - 验证方式:在
sendNotificationEmail里打印调用的方法信息,比如:Method method = SecurityEncryption.class.getDeclaredMethod("desencriptarString", 参数类型1, 参数类型2); System.out.println("调用的方法:" + method.getName() + ",参数类型:" + Arrays.toString(method.getParameterTypes())); - 解决:调整Mock的匹配条件,确保覆盖实际调用的方法签名,比如用
eq()指定具体参数,或明确参数类型的any(XXX.class)
2. 确认静态Mock的作用时机
如果notificationSendEmailService的实例在try-with-resources块之前就触发了desencriptarString调用(比如类的静态初始化块、实例构造方法中调用),此时静态Mock还未生效,会返回真实值或null:
- 检查
notificationSendEmailService的构造逻辑、类静态代码块,确保没有提前调用该静态方法 - 若无法避免提前调用,可尝试将
mockStatic的创建移至@BeforeEach中(注意资源释放,避免测试污染)
3. 升级Mockito版本
老版本Mockito(低于3.4.0)对静态方法Mock的支持存在bug,尤其是重载方法、多次Mock场景:
- 检查项目中Mockito的依赖版本,升级到3.x或4.x的稳定版本(如4.11.0)
- Maven依赖示例:
<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>4.11.0</version> <scope>test</scope> </dependency>
4. 验证静态导入的影响
如果被测类中是通过静态导入调用desencriptarString(import static xxx.SecurityEncryption.desencriptarString;),虽然Mockito理论上支持这种调用,但极少数情况下会出现类加载上下文问题:
- 临时修改被测类代码,改为通过
SecurityEncryption.desencriptarString()的方式调用,测试是否恢复正常
内容的提问来源于stack exchange,提问作者BAPF123
相关产品推荐
相关产品推荐

