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

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)目录下
  • 原代码有两处可提前修正避免测试报错:
    1. 返回值拼写错误:public Orderresponse findOrders() 需改为 public OrderResponse findOrders()
    2. 异常格式化参数缺失:String.format("error", result.statusCode()) 建议改为 String.format("request error, status code: %s", result.statusCode())

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 08:33:03