httptest.Server 是最直接的 HTTP API Mock 方式,它不走网络、不依赖外部服务,通过启动本地 HTTP 服务并注入 srv.URL 替换硬编码地址实现;关键在于让被测代码使用该服务,需将基础 URL 抽成可配置字段或参数,测试后调用 srv.Close() 避免端口泄漏。
httptest.Server 是最直接的 HTTP API Mock 方式
它不走网络、不依赖外部服务,启动一个本地 http 服务返回你指定的响应。关键不是“怎么伪造”,而是“怎么让被测代码用上这个服务”。
常见错误:只调用 httptest.NewServer,却没把 srv.URL 注入到实际客户端里。
- 被测代码中 HTTP 请求地址必须可配置,不能硬编码
"https://api.example.com" - 推荐做法:把 base URL 抽成结构体字段或函数参数,测试时传入
srv.URL(注意是http://开头,httptest.Server不支持 HTTPS) - 务必在测试末尾调用
srv.Close(),否则端口泄漏,多次运行会失败 - handler 中应完整处理路由、method、header 和 body,不要在测试里拼接路径,避免行为和生产不一致
别用 httpmock,除非你改不了被测代码
httpmock 通过替换 http.DefaultTransport 拦截请求,对调用方透明,但极其脆弱。
最常踩的坑:被测代码用了自定义 http.Transport(比如设置了 timeout 或 proxy),httpmock 就完全失效,且不报错,请求照常发到真实网络。
- 必须在测试开始前调用
httpmock.Activate(),结束时调用httpmock.DeactivateAndReset() - 匹配规则优先用
httpmock.RegisterResponder("GET", "https://api.example.com/users"),避免通配符漏匹配 - 返回 JSON 时用
httpmock.NewStringResponder(200, `{"id":1}`),否则Content-Type缺失,可能导致解析失败
手写 fake 比 gomock 更快更稳
绝大多数场景下,为接口写一个轻量 struct 实现,比用 gomock 生成一堆 mock 代码更高效、更易调试。
错误做法:只实现一两个方法就以为“满足接口了”,Go 会 panic 报 missing method XXX。
- fake 结构体应把行为抽成字段,比如
GetUserFunc func(id int) (*User, error),便于测试中灵活控制返回值 - 方法接收者要用指针类型(
*MockUserService),否则mock.Mock内部反射调用会失败 - 如果第三方包没提供 interface,先封装一层适配器,再让 fake 和真实实现都满足同一接口
Mock 的前提是设计可测试
不是“怎么 Mock”,而是“为什么能 Mock”。Go 没有运行时注入能力,所有 Mock 都依赖显式依赖注入。
硬编码 http.Get、在方法里 new http.Client、参数类型写死为 *datastore.Storage —— 这些都会让 Mock 变成修修补补的体力活。
- HTTP 客户端必须作为参数或字段传入,而不是在业务逻辑里创建
- 接口要小而具体,比如
type UserFetcher interface { GetByID(id string) (*User, error) },别搞大而全的Service接口 - 真实存储、fake、第三方 SDK 包装器,三者应实现同一个接口,业务函数只依赖该接口值
最容易被忽略的一点:Mock 不是目标,控制输入输出、隔离不稳定依赖才是。很多测试卡在“怎么生成 mock 代码”,其实问题出在函数签名和构造方式上——先改那几行,Mock 自然就简单了。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











