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

Spring Boot JUnit5 Mockito when-thenReturn失效致NPE问题

问题分析与解决方案

核心问题

当控制器中token赋值为空字符串""时,Mockito的Stub未生效,clusterService.startPatchingTest()返回默认值null,导致调用result.toLowerCase()触发空指针异常(NPE);但将token改为null时测试正常通过。

原因

Mockito的anyString()匹配器存在行为限制:仅匹配非null的字符串(包括空字符串""),但部分旧版本Mockito中anyString()会匹配null,这就导致了测试出现看似矛盾的现象:

  • 当token = null时,若你的Mockito版本兼容null匹配,Stub生效返回"OK",测试通过;
  • 当token = ""时,理论上anyString()应匹配空字符串,但可能因参数匹配的细节差异(如对象实例匹配逻辑、Mockito版本兼容问题)导致Stub未触发,返回null引发NPE。

解决方案

1. 修改Mockito匹配器,兼容null与空字符串

将测试中第三个参数的anyString()替换为any(String.class)或nullable(String.class),这两个匹配器可以兼容null和任意字符串(包括空字符串):

// 方案1:使用any(String.class)匹配任意String类型对象(含null)
when(clusterService.startPatchingTest(any(), anyString(), any(String.class), anyString())).thenReturn("OK");

// 方案2:使用nullable(String.class)明确匹配可空的String参数
when(clusterService.startPatchingTest(any(), anyString(), nullable(String.class), anyString())).thenReturn("OK");

2. 控制器中增加null安全校验

即使Stub生效,也要避免业务代码因result为null触发NPE,在控制器中添加null检查:

@PostMapping("/patch/clustertest/{clustername}/host/{hostname}")
public ResponseEntity<?> patchClusterTestVM(@PathVariable("clustername") String clusterName, @PathVariable("hostname") String hostName) {
    String token = "";
    String uuid = UUID.randomUUID().toString();     
    String result = clusterService.startPatchingTest(new ClusterDetailsClass(1L, "mycluster"), hostName, token, uuid);
    
    // 增加null校验,避免NPE
    if (result == null) {
        return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
    }
    
    return new ResponseEntity<>(result.toLowerCase(), HttpStatus.OK);
}

内容的提问来源于stack exchange,提问作者Zeeshan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 00:44:50