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

SpringBoot测试中Mockito mock RestTemplate的postForEntity方法报错求解

问题根因

你当前的Mock逻辑存在3个核心错误,导致打桩不生效:

  1. 未覆盖token生成接口的Mock:业务代码执行getEvementsReleves时会优先调用generateRemoteToken方法获取token,该方法内调用了postForEntity请求token接口,但你完全没有对这个调用打桩,仅Mock了业务数据接口的调用。
  2. 方法匹配错误:业务数据接口的调用用的是exchange+HttpMethod.GET,但你后续调整时错误地打了postForEntity的桩,方法签名完全不匹配。
  3. 参数匹配失效:你用了精确对象匹配来设置打桩规则,但业务代码里生成的URI、HttpEntity和测试代码里new的对象不是同一个实例,Mockito默认的equals匹配会直接失败,导致打桩规则不触发。
  4. 多余的Spy调用:@Mock已经生成了Mock对象,不需要再调用Mockito.spy(restTemplate),属于无效逻辑。

修复方案

1. 补全token接口的打桩逻辑

在@Before方法中实现你预留的initAuthentificationMock方法,Mock token生成接口的调用:

private void initAuthentificationMock() {
    // 构造符合oauth2返回格式的mock响应
    String mockTokenResp = "{\"access_token\": \"" + MOCKED_TOKEN_VALUE + "\"}";
    ResponseEntity<String> tokenResp = new ResponseEntity<>(mockTokenResp, HttpStatus.OK);
    // 用Mockito参数匹配器匹配所有postForEntity调用,避免实例匹配失效
    Mockito.doReturn(tokenResp).when(restTemplate)
        .postForEntity(
            ArgumentMatchers.any(URI.class),
            ArgumentMatchers.any(HttpEntity.class),
            ArgumentMatchers.eq(String.class)
        );
}

同时删除beforeEach方法里的Mockito.spy(restTemplate)行。

2. 修正业务数据接口的打桩逻辑

把initEvementsRelevesMock里的打桩代码改为匹配exchange方法调用:

ResponseEntity<String> mockedResponse = new ResponseEntity<>(json, HttpStatus.OK);
Mockito.doReturn(mockedResponse).when(restTemplate)
    .exchange(
        ArgumentMatchers.anyString(),
        ArgumentMatchers.eq(HttpMethod.GET),
        ArgumentMatchers.any(HttpEntity.class),
        ArgumentMatchers.eq(EnergyV1ConsumptionReading[].class)
    );

补充说明

如果需要更精确的参数匹配,可以把any(URI.class)/anyString()替换为eq(你的目标URI/URL),只要保证参数值和业务代码生成的一致即可。

内容的提问来源于stack exchange,提问作者Adrien Ruffié

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 00:24:03