test函数不执行需检查三处:文件名必须为xxx_test.go、函数名必须为testxxx格式、参数类型必须为*testing.t;httptest.newrecorder用于handler逻辑单元测试,newserver仅用于需真实网络栈的集成测试;mock应优先手写fake接口而非自动生成。

Test 函数不执行?检查这三处硬性门槛
Go 的测试函数不是写了就能跑——漏掉任意一条,go test 会静默跳过,连失败提示都没有。
- 文件名必须是
xxx_test.go,不能是test_xxx.go或xxx_test.go.txt - 函数名必须是
TestXxx格式(首字母大写 + 驼峰),testXxx、Testxxx、test_xxx全部无效 - 参数类型必须严格为
*testing.T,写成testing.T(少指针)或*testing.B(性能测试)会导致编译失败或被忽略
常见现象:改完代码后 go test -v 显示 “no tests to run”,其实是文件名或函数签名错了。别猜,先核对这三项。
httptest.NewRecorder 还是 httptest.NewServer?按测试目标选
单元测试和集成测试的边界,就卡在要不要真实网络栈——选错工具,要么测得假,要么跑得慢。
- 用
httptest.NewRecorder:只验证 handler 逻辑,比如 status code、JSON body 结构、header 是否设置。它不占端口、不监听、不走 TCP,适合 95% 的 API 单元测试场景 - 用
httptest.NewServer:需要测重定向、Cookie 持久化、客户端自动跟随跳转、或依赖http.Client行为时才用。它返回真实 URL(含http://前缀),别手动拼接
错误做法:所有测试都起 NewServer,结果 CI 里端口冲突、超时、并发不稳定。真正需要它的场景其实很少。
mock 外部依赖时,fake 比 mockgen 更稳
Go 里“mock”不是越自动越好——生成的 mock 对象往往带大量 boilerplate,还容易因接口变更崩掉;而手写 fake,轻量、可控、一眼看懂。
- 先抽象接口,比如
type DB interface { QueryRow(string, ...interface{}) (*sql.Row, error) } - 测试时写一个
fakeDB结构体,只实现你当前用到的方法,返回预设值或错误 - 避免用
monkey或全局 patch:它们破坏类型安全,且在 go 1.21+ 下可能失效
典型坑:handler 里直接调 db.QueryRow,没抽接口——测试时只能连真实数据库,要么慢,要么脏数据污染其他用例。
表格测试里闭包变量共享?必须重声明 tt
这是 Go 测试里最隐蔽也最高频的 bug:循环中不重声明结构体变量,所有子测试用的都是最后一轮的值。
- 写法必须是
for _, tt := range tests { tt := tt // 关键! - 子测试名建议用描述性字符串,比如
"valid_json"、"missing_token",别用"case1" - 每个
t.Run内部独立作用域,defer、panic、goroutine 不会跨用例泄漏
不加 tt := tt 的后果:10 个测试用例全跑最后一个输入,你以为覆盖了边界条件,其实只测了一次。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











