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

MockRestServiceServer返回Null ResponseEntity问题排查求助

问题分析与解决方案

你的ResponseEntity始终为null,核心原因是MockRestServiceServer的请求匹配条件和实际发送的请求不匹配,导致模拟服务器未触发预设响应,RestTemplate调用自然返回null。以下是具体问题点和修复步骤:

1. RestTemplate实例不一致

测试中创建MockServer时绑定的是oauthClientConfig.getRestTemplate(),但服务类里使用的是iDOCClient.getRestTemplate()。如果这两个不是同一个实例,MockServer根本不会拦截实际请求,直接导致无响应。

修复:确保测试和服务类使用同一个RestTemplate实例:

mockInteractiveServer = MockRestServiceServer.createServer(iDOCClient.getRestTemplate());

2. 请求URL不匹配

测试里用requestTo(new URI("mockURI"))指定匹配URL,但实际服务发送的是iDOCClient.getRequestUrl() + "/interactive-documents",两者完全不一致,MockServer不会匹配到该请求。

修复:统一测试和实际代码中的URL:

String expectedUrl = iDOCClient.getRequestUrl() + "/interactive-documents";
mockInteractiveServer
    .expect(ExpectedCount.once(), requestTo(expectedUrl))
    // 其他匹配逻辑...

3. 请求体匹配错误

测试中用content().string("validation content")验证请求体,但实际发送的是MyTicket对象序列化后的JSON字符串,两者完全不匹配,MockServer会判定请求不符合条件,不返回响应。

修复:使用JSON匹配方式验证请求体:

// 构建和服务类中一致的请求对象
TicketRequest expectedRequest = myBuilder.buildTicketRequest();
// 序列化为JSON字符串
ObjectMapper objectMapper = new ObjectMapper();
String expectedRequestJson = objectMapper.writeValueAsString(expectedRequest);

mockInteractiveServer
    .expect(ExpectedCount.once(), requestTo(expectedUrl))
    .andExpect(method(HttpMethod.POST))
    .andExpect(content().json(expectedRequestJson)) // 替换为JSON匹配
    .andRespond(withStatus(HttpStatus.OK).headers(responseHeaders));

额外补充:服务类返回逻辑

你的测试期望获取sampleTicketId,但当前服务类的myMethod未实现从响应头提取ID的逻辑,需补充:

public String myMethod(CreateTicketRequest createTicketRequest){
    TicketRequest request = myBuilder.buildTicketRequest();
    HttpHeaders headers = new HttpHeaders();
    headers.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
    ResponseEntity<String> createTicketResponse = iDOCClient.getRestTemplate()
            .postForEntity(iDOCClient.getRequestUrl() + "/interactive-documents", request, String.class);
    
    // 从Location头提取ticketId
    String location = createTicketResponse.getHeaders().getFirst("Location");
    return location.split("/")[1]; // 适配samplePrefix/sampleTicketId格式
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 06:35:26