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

Mock WebClient Post方法时.body处出现NullPointerException问题

问题:Mock WebClient Post方法时在.body()处触发NullPointerException

在Mock WebClient的Post方法时,执行到.body(Mono.just(createReq), CreateReq.class)处出现NullPointerException。已确认createReq不为空,尝试将请求体改为字符串形式(.body(req, String.class))后仍触发该异常。

业务代码

public class RepoService {
    @Autowired
    private WebClient webClient;

    public DIResponse createIdentity(DICreateRequest diCreateRequest) {
        CreateReq createReq = diCreateRequestMapper.setRequest(diCreateRequest);
        DIResponse diResponse = null;

        UriComponents uriBuilder = UriComponentsBuilder
                .fromUriString(url)
                .build(false);

        DIResponse apiResponse = webClient
                .post()
                .uri(uriBuilder.toUriString())
                .body(Mono.just(createReq), CreateReq.class)  // 此处触发NullPointerException
                .retrieve()
                .onStatus(HttpStatus::is4xxClientError, clientResponse -> clientResponse.bodyToMono(DIBadRequest.class).flatMap(errorResponse -> {
                    LOGGER.error(CLIENT_ERROR, "POST", clientResponse.statusCode(), errorResponse);
                    return Mono.error(new DataAccessException(ERROR_STATUS +clientResponse.statusCode()+ ERROR_DESC+ errorResponse.getDetail()));
                }))
                .bodyToMono(DIResponse.class)
                .block();

        return apiResponse;
    }
}

JUnit测试用例

@Mock
private WebClient webClient;

@Mock
WebClient.RequestHeadersUriSpec requestHeadersUriSpecMock;
@Mock
WebClient.RequestBodyUriSpec requestBodyUriSpecMock;

@Mock
WebClient.RequestBodySpec requestBodySpecMock;

@Mock
WebClient.RequestHeadersSpec requestHeadersSpecMock;

@Mock
WebClient.ResponseSpec responseSpecMock;

@InjectMocks
private RepoService repositoryService;

@Test
void testCreateIdentity() throws IOException {
    DICreateRequest mockDICreateRequest = getMockDICreatReq();
    CreateReq createReq = createDI();
    DIResponse mockDIResponse = getDI();

    when(diCreateRequestMapper.setRequest(mockDICreateRequest)).thenReturn(createReq);

    when(webClient.post()).thenReturn(requestBodyUriSpecMock);
    when(requestBodyUriSpecMock.uri((URI) any())).thenReturn(requestBodySpecMock);
    when(requestBodySpecMock.body(any())).thenReturn(requestHeadersSpecMock);
    when(requestHeadersSpecMock.retrieve()).thenReturn(responseSpecMock);
    when(responseSpecMock.onStatus(any(), any())).thenReturn(responseSpecMock);
    Mockito.when(responseSpecMock.bodyToMono(DIResponse.class)).thenReturn(Mono.just(mockDIResponse));

    DIResponse result = repositoryService.createIdentity(mockDICreateRequest);

    Assert.assertEquals(mockDIResponse.getId(), result.getId());
}

解决方案

问题根源

测试用例存在两处Mock匹配错误:

  1. body()方法重载不匹配:业务代码调用的是body(Publisher<? extends T>, Class<T>)重载,但测试仅Mock了body(Object)版本,导致实际调用时无对应Mock返回,返回null触发NPE。
  2. uri()方法参数类型不匹配:业务代码传入的是String类型的URI,但测试Mock的是URI对象类型的参数,导致匹配失败,后续调用链中断返回null。

修复代码

修改测试用例中的两处Mock语句:

  1. 修正uri()方法的Mock,匹配String类型参数:
// 替换原有的when(requestBodyUriSpecMock.uri((URI) any())).thenReturn(requestBodySpecMock);
when(requestBodyUriSpecMock.uri(anyString())).thenReturn(requestBodySpecMock);
  1. 修正body()方法的Mock,匹配正确的重载:
// 替换原有的when(requestBodySpecMock.body(any())).thenReturn(requestHeadersSpecMock);
when(requestBodySpecMock.body(any(Publisher.class), eq(CreateReq.class))).thenReturn(requestHeadersSpecMock);

如果后续需要测试字符串请求体的场景,补充对应的Mock:

when(requestBodySpecMock.body(any(Publisher.class), eq(String.class))).thenReturn(requestHeadersSpecMock);

修改后重新运行测试,即可解决NullPointerException问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 11:57:40