You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 10:10:03