go-pact启动报connection refused的根本原因是Pact Mock Server未手动启动,go-pact仅是客户端SDK,默认连接localhost:1234但该端口无监听进程;必须npm安装pact-cli后运行pact-mock-service,并在Go测试中显式配置Host/Port,且HTTP请求须全部打向mock地址。

Go 微服务做契约测试,不能直接跑 go test 就出 pact 文件——必须手动启动 Pact Mock Server,且所有 HTTP 请求必须打到它监听的地址,否则 interaction 为空、验证必挂。
为什么 go-pact 启动就报 connection refused
根本不是代码写错了,而是 Pact Mock Server 根本没起来。go-pact 是个客户端 SDK,不自带服务进程,它默认尝试连 http://localhost:1234,但这个端口没人监听。
- 先装 CLI:
npm install -g pact-cli - 再手动启服务:
pact-mock-service --port 1234 --host localhost - Go 测试里别依赖默认配置,显式传参:
NewPact(PactConfig{Host: "localhost", Port: 1234}) - CI 环境(Linux Docker)要提前在镜像里装好
pact-cli,否则command not found
消费者测试里 HTTP 请求为什么没被记录
因为请求没发到 Pact Mock Server。常见错误是 client 初始化写死真实域名,比如 NewClient("https://api.example.com"),结果请求飞走了,mock 完全没感知。
- 测试中必须用
pact.MockServiceURL()动态构造 client:client := NewClient(pact.MockServiceURL()) -
AddInteraction()必须在 HTTP 调用前执行,顺序错则 interaction 不生效 - 每个测试用例末尾必须调
pact.Teardown(),否则 pact 文件可能写一半或为空 - 并发测试(
t.Parallel())时,每个测试需独立pact实例,否则 interaction 互相覆盖
VerifyProvider 总报 no interactions found
不是 pact 文件没生成,而是路径、命名或匹配逻辑对不上。Provider 验证是“按名索引 + 按路径匹配”,错一个字符就失败。
立即学习“go语言免费学习笔记(深入)”;
-
PactURLs必须显式指定完整路径,如./pacts/order-service-inventory-service.json,不能只写目录 - 文件名必须严格为
{consumer-name}-{provider-name}.json,大小写、连字符都不能差 -
consumer.name和provider.name字段值,必须和验证时传入的ProviderName/ConsumerName完全一致 - Provider 接口实际响应的
status、Content-Type、JSON 字段名大小写,必须和 pact 文件里声明的一模一样
WithRequest 和 WithResponse 哪些字段不能省
省略 Method、Path、Status 中任意一个,验证阶段会静默跳过匹配,报错信息只显示 mismatched headers 或 no interactions matched,非常难定位。
-
Path只填路径段,如/api/orders,不要带 query 参数;query 单独填Query字段 - 响应体含动态字段(ID、时间戳等)必须用
dsl.Like()或dsl.EachLike(),不能直接写死值 - 如果契约声明了
Content-Type: application/json,Provider 返回text/plain会失败,但错误提示不明确,得手动比对头字段
最容易被忽略的是:Provider 验证不是静态读 JSON,而是向真实服务发一次 HTTP 请求,然后逐字段比对响应。这意味着你得确保 Provider 进程已启动、路由注册正确、且中间件(如 auth、cors)不会拦截或改写响应结构——哪怕只多一个空格,也可能导致验证失败。



















