httptest.Server是Go中轻量Mock外部API的首选方案,三步即可:写handler(设Content-Type、多路径用ServeMux、校验method/query)、启server(返回随机端口URL)、替换client endpoint;须defer Close()防端口泄漏,路径与前端请求严格对齐。

直接用 httptest.Server 搭 Mock 服务,别碰 Prism、MockServer 或完整 Web 框架——它们要么跨语言依赖重,要么引入路由冲突和端口泄漏风险,而 httptest.Server 启动快、零外部依赖、可嵌入测试、自动回收端口,是前后端并行开发中最稳的起点。
怎么用 httptest.Server 快速起一个可联调的 Mock API
核心就三步:写 handler → 启 server → 替换 client 的 endpoint。它不监听真实端口(而是随机绑定本地回环地址),也不需要 go run main.go 单独启动进程,直接在测试或 main 函数里调用即可。
-
httptest.NewServer返回的srv.URL是类似http://127.0.0.1:42193的地址,必须传给被测 client(比如client.Endpoint = srv.URL),硬编码"https://api.example.com"就白搭 - handler 里务必显式设置
w.Header().Set("Content-Type", "application/json"),否则 Go 的json.Unmarshal可能静默跳过字段 - 别在全局变量里复用
srv,每次调用httptest.NewServer都要配对defer srv.Close(),否则并发测试会因端口耗尽失败 - 如果前端发的是
fetch("/api/users"),Mock handler 的路径就得是/api/users,别省略前缀——路径不一致会导致 404,且不易排查
如何让 Mock 支持多路径、不同状态码和请求校验
单个 http.HandlerFunc 很快会变得难维护。改用 http.ServeMux 显式注册路由,再在每个 handler 内部用 r.Method 和 r.URL.Query() 控制行为,比堆 if-else 更清晰。
-
ServeMux不自动区分 HTTP 方法,GET /api/user和POST /api/user必须在 handler 里用switch r.Method分支处理,漏判会返回 405 - GET 参数用
r.URL.Query().Get("id")安全;POST JSON 要先io.ReadAll(r.Body)拿原始字节,再json.Unmarshal,重复读r.Body会得到空内容 - 模拟错误响应时,别只写
w.WriteHeader(401),记得补 body,比如w.Write([]byte(`{"error":"unauthorized"}`)),否则前端可能卡在 parse 阶段 - 路径末尾斜杠有语义:
/api/会匹配/api/users,但/api不会——Mock 场景建议写全路径,避免歧义
为什么不要在测试里改 http.DefaultClient
全局替换 http.DefaultClient.Transport 看似省事,实则破坏测试隔离性:并行测试可能互相覆盖 Transport,或漏还原导致后续测试发请求到真实网络。正确做法是让被测代码接受 *http.Client 参数,测试时传入自定义 client。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
立即学习“go语言免费学习笔记(深入)”;
- 新建 client 时传
&http.Client{Transport: mockTransport},其中mockTransport可以是手写的RoundTripper实现,也可以是httptest.NewUnstartedServer配合Handler - 若第三方 SDK 强制用
http.DefaultClient且无法改源码,才考虑httpmock,但必须确认它没自定义Transport,否则拦截完全失效 -
httpmock.Activate()和httpmock.DeactivateAndReset()必须成对出现,且不能跨测试函数共享状态
前后端联调时,Mock 服务怎么对接 Vite/React 开发服务器
开发阶段,前端走 Vite HMR(http://localhost:5173),后端 Mock 服务跑在随机端口(如 http://127.0.0.1:38214),两者通过 Vite 的 proxy 中转,而不是让 Go 服务同时托管前端资源。
- Vite 配置
server.proxy把/api前缀代理到srv.URL,例如:target: "http://127.0.0.1:38214",这样fetch("/api/users")实际打到 Mock 服务 - Go 的 Mock handler 路径必须与 proxy 规则一致(都带
/api前缀),否则 404 - 不要在 Go 里写 CORS 中间件来“适配前端”,代理已解决跨域问题;CORS 只需在生产部署 Nginx 或负载均衡层配置
- Mock 返回的 JSON 结构必须和真实 API 一致,字段名、嵌套层级、空值处理都要对齐,否则前端解构时出现
undefined或运行时错误
最常被忽略的一点:Mock 的 JSON 字段名大小写、下划线风格必须和真实响应严格一致,json: tag 写错一个字母,json.Unmarshal 就静默跳过——建议直接从线上响应 copy-paste 到测试里,而不是手写结构体或拼接字符串。

















