使用Quarkus/JUnit进行集成测试时,如何校验出站HTTP请求体?
基于Quarkus、JUnit、Test Containers和WireMock拦截校验动态出站HTTP请求的集成测试方案
问题背景
技术栈:Quarkus、JUnit、Test Containers、WireMock
业务流程:
- 应用接收请求
- 处理并转换接收的数据,将转换后的数据存入数据库
- 将转换后的请求转发至动态变化的外部端点,同时向Kafka发送消息触发后续流程
- 向调用方返回200状态码(空响应体)
测试需求:验证步骤3中出站请求的目标地址是否正确,以及请求体是否符合转换预期。
现有方案的局限
- 校验数据库中存储的转换后数据:仅能验证转换结果,无法确认请求是否实际发送、发送地址是否正确
- 校验Kafka消息:同样无法验证出站请求的发送状态和目标地址
可行落地方案
核心思路
通过WireMock容器模拟外部服务,同时利用Quarkus的配置覆盖/请求拦截机制,将动态生成的出站地址替换为WireMock容器地址,从而拦截所有出站请求并完成校验。
具体实现步骤
- 启动WireMock Test Container
在测试类中声明WireMock容器,自动获取动态端口:
@Container static WireMockContainer wireMock = new WireMockContainer("wiremock/wiremock:3.3.1") .withExposedPorts(8080);
- 覆盖基础地址配置(适配基础路径+动态后缀场景)
如果出站地址是"基础地址+动态路径后缀"的形式,直接通过系统属性覆盖基础地址配置:
@BeforeEach void setup() { // 假设业务代码通过"external.service.base-url"读取基础地址 System.setProperty("external.service.base-url", wireMock.getBaseUrl()); }
- 配置WireMock捕获并验证请求
针对动态路径配置通用stub,触发业务流程后校验请求细节:
@Test void verifyOutboundRequest() { // 配置WireMock接收任意POST请求并返回200 wireMock.stubFor(post(anyUrl()) .willReturn(aResponse().withStatus(200))); // 调用应用接口触发业务流程 given() .contentType(ContentType.JSON) .body(originalRequestPayload) .when() .post("/app/entry-endpoint") .then() .statusCode(200); // 验证出站请求的目标路径和请求体 wireMock.verify(postRequestedFor(urlEqualTo("/expected-dynamic-path")) .withRequestBody(equalToJson(expectedTransformedPayload))); }
- 请求拦截重定向(适配完全动态地址场景)
如果出站地址是完全无规律的动态地址,通过Quarkus的ClientRequestFilter拦截并重定向所有出站请求到WireMock:
@Provider public class TestRequestRedirectFilter implements ClientRequestFilter { @Override public void filter(ClientRequestContext requestContext) throws IOException { // 保留原路径,替换域名端口为WireMock地址 URI wireMockUri = URI.create(wireMock.getBaseUrl() + requestContext.getUri().getPath()); requestContext.setUri(wireMockUri); } }
在测试类中注册该过滤器:
@QuarkusTest @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class OutboundRequestTest { static WireMockContainer wireMock = new WireMockContainer("wiremock/wiremock:3.3.1") .withExposedPorts(8080); static { wireMock.start(); // 注册拦截过滤器 ResteasyClientBuilder.newBuilder().register(TestRequestRedirectFilter.class); } }
关键优势
- 直接拦截出站请求,同时验证发送状态、目标地址和请求体
- 完全适配动态变化的外部端点场景
- 与现有技术栈无缝集成,无需修改业务代码
内容的提问来源于stack exchange,提问作者pvsfair
相关产品推荐
相关产品推荐

