Spring Boot下使用WebClient编写Pact消费者契约的测试问题
WebClient 集成 Pact 消费者契约测试实现方案
第一步:引入依赖
以Maven为例,添加Pact消费者测试相关依赖:
<!-- Pact JUnit5 消费者核心依赖 --> <dependency> <groupId>au.com.dius.pact.consumer</groupId> <artifactId>junit5</artifactId> <version>4.6.11</version> <scope>test</scope> </dependency> <!-- Reactive栈适配依赖,适配WebClient响应式场景 --> <dependency> <groupId>au.com.dius.pact.consumer</groupId> <artifactId>reactor</artifactId> <version>4.6.11</version> <scope>test</scope> </dependency>
第二步:编写Pact消费者测试类
Pact Mock Server本质是本地启动的真实HTTP服务,不需要对WebClient做任何特殊拦截配置,只需要把Mock Server的地址作为baseURL传入OrdersGateway构造方法即可,WebClient会自然将请求发送到Pact Mock Server。
完整测试代码如下:
@PactTestFor(providerName = "orders-provider", port = "random") public class OrdersGatewayPactTest { // 低版本Pact如果无法自动注入url,可替换为@MockServerHost、@MockServerPort两个注解拼接地址 private String mockServerUrl; private OrdersGateway ordersGateway; @BeforeEach void setup() { // 把Pact Mock Server地址传入Gateway完成初始化 ordersGateway = new OrdersGateway(mockServerUrl); } // 定义契约交互规则 @Pact(consumer = "orders-consumer") public RequestResponsePact findOrdersPact(PactDslWithProvider builder) { // 根据实际的OrderResponse字段定义响应结构匹配规则 DslPart responseBody = new PactDslJsonBody() .stringType("orderId", "12345") .numberType("amount", 99.9) .stringType("status", "SUCCESS"); return builder .given("orders exist for query") .uponReceiving("request to query order list") .path(OrdersGateway.PATH) .method("POST") .matchHeader(HttpHeaders.ACCEPT, MediaType.ALL_VALUE) .matchHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .willRespondWith() .status(200) .body(responseBody) .toPact(); } // 契约验证测试方法 @Test @PactTestFor(pactMethod = "findOrdersPact") void verifyFindOrdersContract() { // 调用业务方法,请求会自动发往Pact Mock Server OrderResponse response = ordersGateway.findOrders(); // 断言返回结果符合预期 assertNotNull(response); assertEquals("12345", response.getOrderId()); assertEquals(99.9, response.getAmount()); assertEquals("SUCCESS", response.getStatus()); } }
补充说明
- Pact会自动校验请求是否符合定义的契约规则:如果WebClient发送的请求头、方法、路径和预定义的契约不一致,测试会直接失败
- 测试执行完成后,契约文件会自动生成到
target/pacts(Maven)或build/pacts(Gradle)目录下 - 原代码有两处可提前修正避免测试报错:
- 返回值拼写错误:
public Orderresponse findOrders()需改为public OrderResponse findOrders() - 异常格式化参数缺失:
String.format("error", result.statusCode())建议改为String.format("request error, status code: %s", result.statusCode())
- 返回值拼写错误:
内容的提问来源于stack exchange,提问作者user1555190
相关产品推荐
相关产品推荐

