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

Spring MockRestServiceServer是否提供现成的请求体捕获类/方法用于日志记录与调试?

实现MockRestServiceServer请求体捕获的现成方案

其实Spring Test里并没有直接提供你期望的andCapture方法,但有非常便捷的现成方式可以实现这个功能——利用RequestMatcher接口来捕获请求体,完全能满足你日志记录或调试验证的需求。

方法一:自定义捕获器类(复用性高)

如果你需要在多个测试用例里复用捕获逻辑,可以写一个简单的RequestBodyCaptor类实现RequestMatcher:

import org.springframework.http.client.ClientHttpRequest;
import org.springframework.test.web.client.RequestMatcher;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class RequestBodyCaptor implements RequestMatcher {
    private String capturedBody;

    @Override
    public void match(ClientHttpRequest request) throws IOException {
        // 读取并保存请求体
        this.capturedBody = new String(request.getBody().toByteArray(), StandardCharsets.UTF_8);
        // 直接在这里打日志或者做其他操作
        System.out.printf("Captured request body: %s%n", capturedBody);
    }

    public String getCapturedBody() {
        return capturedBody;
    }
}

然后在测试中使用:

import org.springframework.test.web.client.MockRestServiceServer;
import org.springframework.web.client.RestTemplate;
import org.junit.jupiter.api.Test;
import static org.springframework.test.web.client.MockRestRequestMatchers.*;
import static org.springframework.test.web.client.MockRestResponseCreators.withSuccess;

class MyTest {
    private final RestTemplate restTemplate = new RestTemplate();

    @Test
    void myTest() {
        MockRestServiceServer mockServer = MockRestServiceServer.createFor(restTemplate);
        RequestBodyCaptor bodyCaptor = new RequestBodyCaptor();

        mockServer
            .expect(method(HttpMethod.POST))
            .andExpect(requestTo("http://mock.example.com/myservice"))
            .andExpect(bodyCaptor) // 插入捕获逻辑
            .andRespond(withSuccess("The mock response", MediaType.TEXT_PLAIN));

        // 发送测试请求
        restTemplate.postForObject("http://mock.example.com/myservice", "Hello Mock!", String.class);

        // 后续可以获取捕获的body做验证或日志
        System.out.println("Saved body for verification: " + bodyCaptor.getCapturedBody());
    }
}

方法二:内联Lambda(快速临时使用)

如果只是单个测试用例需要捕获,直接用lambda表达式写在andExpect里更简洁,不用额外写类:

@Test
void myTest() {
    MockRestServiceServer mockServer = MockRestServiceServer.createFor(restTemplate);
    StringBuilder capturedBody = new StringBuilder();

    mockServer
        .expect(method(HttpMethod.POST))
        .andExpect(requestTo("http://mock.example.com/myservice"))
        .andExpect(request -> {
            try {
                String body = new String(request.getBody().toByteArray(), StandardCharsets.UTF_8);
                capturedBody.append(body);
                // 直接打印日志
                log.info("Incoming request body: {}", body);
            } catch (IOException e) {
                throw new AssertionError("Failed to read request body", e);
            }
        })
        .andRespond(withSuccess("The mock response", MediaType.TEXT_PLAIN));

    // 发送请求
    restTemplate.postForObject("http://mock.example.com/myservice", "Test Payload", String.class);

    // 验证捕获的内容
    assertEquals("Test Payload", capturedBody.toString());
}

原理说明

RequestMatcher原本是用来验证请求是否符合预期的,但它的match方法会传入完整的ClientHttpRequest对象,我们可以利用这个特性读取请求体并做任何我们需要的操作——不管是日志记录还是保存下来后续验证,都完全可行。

这种方式完全符合Spring Test的设计模式,不需要额外引入第三方依赖,是官方推荐的扩展方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 09:47:44