gock仅拦截http.get/http.post及http.defaultclient.do()请求,自定义*http.client需显式替换为gock.newclient();规则须协议、主机、路径、方法、header、body全匹配,测试前后必须调用gock.off()或gock.flush()清理。

gock 能否拦截你代码里的 HTTP 请求
能,但只拦两种情况:http.Get/http.Post 等默认函数调用,或显式使用 http.DefaultClient 的 Do();如果你封装了带超时/重试的自定义 *http.Client,gock 默认完全不生效。
常见错误现象:gock.Intercept() 后测试仍发真实请求,或报错 Get "https://api.example.com": dial tcp: lookup api.example.com: no such host——这说明请求压根没进 gock,而是直连 DNS 了。
- 确认业务代码没自己 new
*http.Client,也没复写Transport - 如果用了自定义 client(比如
&http.Client{Timeout: 5 * time.Second}),必须在测试中替换成gock.NewClient()返回的 client,并注入到被测对象里 - 别用
curl、http.Transport直接 dial、h2c 协议——这些 gock 压根不碰
注册规则时 URL 和方法必须严格匹配
gock 规则不是模糊匹配,是字段级精确比对:协议、主机、路径、HTTP 方法、Header、Body 全部要对得上。默认只认 GET 和完整路径,其余全得手动声明。
例如你调用 http.Post("https://api.example.com/v1/users", "application/json", body),但只写 gock.New("https://api.example.com").Get("/v1/users") → 完全不命中。
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
-
POST请求必须用Post(),不是Get() - 路径末尾斜杠敏感:
/v1/users≠/v1/users/ - 含
Authorization头?得加.MatchHeader("Authorization", "Bearer .+"),否则忽略 - JSON body 推荐用
.MatchType("json").JSON(map[string]interface{}{"name": "alice"}),别手撕字节流
测试前后必须清理 gock 状态
gock 规则是全局注册的,不清理会污染后续测试——表现是某个本不该发请求的测试突然失败,报错 no mock for GET https://xxx,而它根本没走那条逻辑。
- 每个测试函数开头加
defer gock.Off()或defer gock.Flush() -
gock.Off()关闭拦截器,gock.Flush()清空已注册规则;二者选一即可,但不能漏 - 别在
TestMain里统一gock.Off()——多个测试并发跑时会互相干扰 - 如果用了
gock.EnableNetworking()临时放行某请求,务必配对gock.DisableNetworking()
为什么有时规则写了却没触发
最常被忽略的是请求发起时机和 client 绑定关系。gock 拦截发生在 RoundTrip() 阶段,前提是 client 的 Transport 是 gock 包装过的。
- 检查是否误把
gock.NewClient()创建的 client 当成普通 client 传给了别的地方(比如中间件、日志器),导致实际发请求的 client 还是原始的http.DefaultClient - 确认没在测试中途调用
gock.Reset()——它会清掉所有规则,且不可逆 - 用
gock.IsEnabled()在测试里打个日志,确认拦截器确实在运行 - 如果用的是 Go 1.22+,注意
http.DefaultClient在某些构建 tag 下可能被替换,gock 不保证兼容
gock 的规则注册和清理是硬性要求,不是可选项;路径和方法的精确性也不是“尽量匹配”,而是“差一个字符就失效”。真正麻烦的从来不是写规则,而是让请求老老实实走到 gock 的 RoundTrip 里。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










