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

Pact Test消费者端生成契约时出现connection refused连接拒绝错误

Pact消费者契约测试连接拒绝问题排查

问题背景

在消费者端运行Pact契约测试生成契约文件时,持续触发连接拒绝错误,测试用例执行失败,相关代码、配置及错误信息如下:

测试类代码

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, properties = 
"product-service.products.baseUrl:http://localhost:9001/svc-product-service/api/products")
public class ProductServiceContractTest {
@Autowired
private ProductService productService;

@Rule
public PactProviderRuleMk2 provider = new PactProviderRuleMk2("svc-product-service", "localhost", 9001, this);

@Pact(consumer = "svc-product-order-service")
public RequestResponsePact pactProductExists(PactDslWithProvider builder) {
    return builder.given("Product 1001 exists").uponReceiving("A request to /1001").path("/1001").method("GET")
            .willRespondWith().status(200)
            .body(new PactDslJsonBody().integerType("id", 1001).stringType("name", "Laptop"))
            .toPact();
}

@PactVerification(fragment = "pactProductExists")
@Test
public void productExists() {
    final Product product = productService.fetchProductsById(1001);
    assertThat(product.getId()).isEqualTo(1001);
    assertThat(product.getName()).isEqualTo("Laptop");

}

}

Maven依赖配置

<dependency>
   <groupId>au.com.dius</groupId>
   <artifactId>pact-jvm-consumer-java8_2.12</artifactId>
   <version>3.5.24</version>
   <scope>test</scope>
</dependency>

错误堆栈

[ERROR] com.example.product.order.service.ProductServiceContractTest.productExists  Time elapsed: 0.034 s  <<< ERROR!
org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://localhost:9001/svc-product-service/api/products/1001": Connect to localhost:9001 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect; nested exception is org.apache.http.conn.HttpHostConnectException: Connect to localhost:9001 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect
at com.example.product.order.service.ProductServiceContractTest.productExists(ProductServiceContractTest.java:79)
Caused by: org.apache.http.conn.HttpHostConnectException: Connect to localhost:9001 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect
at com.example.product.order.service.ProductServiceContractTest.productExists(ProductServiceContractTest.java:79)
Caused by: java.net.ConnectException: Connection refused: connect
at com.example.product.order.service.ProductServiceContractTest.productExists(ProductServiceContractTest.java:79)

错误核心表现:测试执行时向配置的服务地址发起GET请求,连接localhost:9001端口失败,抛出Connection refused异常导致测试用例失败。

根因分析

连接拒绝错误本质是目标端口没有进程监听,或者请求被路由到了未绑定服务的网络地址,结合代码和错误日志,常见触发原因有三类:

  1. Junit Rule未正常生效,Pact内置的Mock服务没有启动,9001端口无服务监听
  2. 本机IPv6解析优先级高于IPv4,Pact Mock服务默认绑定IPv4回环地址,请求被路由到IPv6地址导致连接失败
  3. 等连接问题修复后,现有代码还存在路径不匹配问题:Pact交互定义的请求路径为/1001,但实际业务代码请求的完整路径为/svc-product-service/api/products/1001,会触发Pact的请求匹配失败

排查解决步骤

  • 检查Junit版本兼容性
    你使用的pact-jvm-consumer-java8_2.12:3.5.24是基于Junit4实现的,若项目中混入Junit5(Jupiter)依赖,会导致@Rule注解不生效,Pact Mock服务不会启动。先排查依赖树,排除Junit5相关的测试依赖,确保测试运行时使用Junit4执行。
  • 验证Mock服务启动状态
    测试执行时,在系统命令行执行端口检查命令:
    • Windows系统:netstat -ano | findstr :9001
    • Mac/Linux系统:lsof -i:9001
      如果没有查询到9001端口的监听进程,说明Mock服务未启动,优先排查测试运行器配置、@Rule字段的访问修饰符(必须为public)是否符合要求。
  • 强制使用IPv4网络栈
    从错误日志可以看到,localhost解析同时返回了IPv4和IPv6地址,给测试任务添加JVM启动参数-Djava.net.preferIPv4Stack=true,强制客户端使用IPv4地址发起连接,避免路由到未绑定的IPv6地址。
  • 修正Pact交互的路径配置
    连接问题解决后,将Pact DSL中定义的请求路径从/1001修改为实际请求的完整路径/svc-product-service/api/products/1001,或者在初始化PactProviderRuleMk2时统一设置上下文路径,保证Mock服务的匹配规则和业务代码的实际请求路径一致,避免出现404或请求不匹配错误。
  • 校验配置注入正确性
    测试启动时打印ProductService中实际使用的baseUrl配置,确认配置值和Pact Mock服务的地址、端口一致,避免配置覆盖导致请求指向未启动的真实服务地址。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 12:36:20