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

Mockito测试中ResponseEntity为空空指针问题的排查与解决咨询

问题:Mockito模拟RestTemplate后仍出现ResponseEntity空指针异常

编写Mockito测试用例时,明明已经对RestTemplate的exchange方法进行模拟,但还是出现ResponseEntity为空的NullPointerException,错误信息如下:

java.lang.NullPointerException: Cannot invoke "org.springframework.http.ResponseEntity.getBody()" because "responseEntity" is null

模拟代码

Mockito.when(restTemplate.exchange(ArgumentMatchers.anyString(), 
                                    Mockito.any(HttpMethod.class), 
                                    ArgumentMatchers.any(), 
                                    ArgumentMatchers.<Class<byte[]>>any()))
       .thenReturn(new ResponseEntity("test".getBytes(), HttpStatus.OK));

业务方法代码

public void getLetters() {
    try {
        List<letters> records = letterRepository.getletters();
        HttpHeaders headers = httpClientToken.getHeader(
            tokenurl,
            Client,
            Secret,
            Granttype
        );

        ResponseEntity<byte[]> responseEntity;
        HttpEntity<?> entity = new HttpEntity<>(headers);

        for(int i = 0; i < records.size(); i++) {
            String Url = "http://localhost:8080/documents/getdocument";

            URI uri = UriComponentsBuilder.fromHttpUrl(Objects.requireNonNull(Url))
                    .queryParam("spaceId", records.get(i).letterId)
                    .build()
                    .toUri();

            try {
                responseEntity = restTemplate.getTemplateAttributesRestTemplate().exchange(uri, HttpMethod.GET, entity, byte[].class);
                
                InputStream anyInputStream = new ByteArrayInputStream(responseEntity.getBody());
                str = "C:\\Users\\hm\\Downloads\\letter.pdf";
                OutputStream outputStream = new FileOutputStream(str);

                copyFile(anyInputStream, outputStream, 1024 * 1024 * 10);
                
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

错误原因

  1. 模拟的RestTemplate实例不匹配:业务代码中调用的是restTemplate.getTemplateAttributesRestTemplate()返回的RestTemplate对象,而你模拟的是外层的restTemplate实例,两者不是同一个对象,导致模拟未生效。
  2. 方法签名不匹配:你模拟的是接收String类型URL的exchange重载方法,但业务代码中调用的是接收URI类型参数的重载方法,参数类型不匹配,模拟的方法逻辑不会被触发,因此返回null。

解决方法

  1. 确保模拟目标实例正确

    • 如果getTemplateAttributesRestTemplate()是当前类的方法,需要额外模拟这个方法,让它返回你已经设置好模拟逻辑的RestTemplate实例:
      Mockito.when(restTemplate.getTemplateAttributesRestTemplate()).thenReturn(yourMockRestTemplate);
      
    • 或者直接确保业务代码中使用的RestTemplate就是你注入的mock实例,避免多层调用导致实例不一致。
  2. 修正模拟的方法签名
    修改模拟代码,匹配接收URI参数的exchange重载方法:

    Mockito.when(yourMockRestTemplate.exchange(ArgumentMatchers.any(URI.class), 
                                               Mockito.any(HttpMethod.class), 
                                               ArgumentMatchers.any(), 
                                               ArgumentMatchers.<Class<byte[]>>any()))
           .thenReturn(new ResponseEntity("test".getBytes(), HttpStatus.OK));
    
  3. 补充测试前置条件
    确保letterRepository.getletters()返回非空列表,这样循环才能执行到exchange调用的逻辑,否则测试无法覆盖到报错代码段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 13:12:54