assert失败后测试继续执行,require失败则立即终止当前用例;mock参数需严格匹配类型和顺序;suite需显式调用run才触发setuptest/teardowntest;嵌套结构体断言应避免reflect.deepequal对未导出字段或map无序的误判。

testify 的 assert 和 require 到底该选哪个
区别不在“强弱”,而在“是否继续执行”。assert 失败只打日志、返回 false,测试函数仍往下跑;require 失败直接调用 t.Fatal(),当前测试用例立刻终止。
常见错误现象:用 assert.Equal(t, expected, actual) 检查一个关键初始化结果,后面却依赖这个结果做操作——一旦前面失败,后面可能 panic 或报错,但错误堆栈指向的是后续代码,不是真正出问题的地方。
- 初始化 DB 连接、读取配置、解析 JSON 后的结构体字段,优先用
require - 校验多个独立字段(比如 API 响应里
Name、Age、Email是否符合预期),用assert一次性看到所有失败项 -
require不会帮你跳过后续断言,它只是提前退出;想“跳过一组相关断言”,得靠逻辑分块或子测试
mock 接口时为什么 mock.On("DoSomething", mock.Anything).Return(...) 总不生效
根本原因通常是参数类型不匹配——mock.Anything 只匹配任意值,但不绕过类型检查。如果被 mock 方法签名是 DoSomething(ctx context.Context, req *Request),而你写 mock.On("DoSomething", mock.Anything, mock.Anything),第二个参数传的是 *OtherStruct,就完全不会命中。
使用场景:单元测试中隔离外部依赖,比如 HTTP client、数据库 driver、第三方 SDK 客户端。
- 务必按方法签名顺序、严格按类型写
mock.On参数,不确定时用mock.MatchedBy(func(v interface{}) bool { ... })自定义判断 - 返回值数量和类型必须与原方法一致,比如原方法返回
(int, error),.Return(42, nil)才合法;少一个或类型错,运行时 panic 报Wrong number or type of return values - 别在测试函数外提前调用
mock.AssertExpectations(t),它只能在测试结束前调用,否则会报Expected call at ... never happened
用 testify/suite 写测试集时,SetupTest 和 TearDownTest 被忽略了
因为没调用 suite.Run(t, new(MySuite))。suite 不是自动注册的,它只是个普通 struct;只有显式调用 Run,框架才会按生命周期调用 SetupTest→测试方法→TearDownTest。
性能影响:每个测试方法都会触发一次 setup/teardown,如果里面做了开 DB 连接、启 HTTP server 等重操作,容易拖慢整体测试速度。
- 确保测试函数名以
Test开头,且接收*testing.T,例如func TestMySuite(t *testing.T) { suite.Run(t, new(MySuite)) } -
SetupSuite和TearDownSuite是整套测试运行前后各一次,适合全局资源(如临时目录、共享 mock server),但要注意并发安全——go test -p=1可强制串行避免竞争 - 别在
SetupTest里用t.Fatal或t.Error,它不参与断言统计;要用require或assert,否则失败了也不会标记测试为 fail
断言嵌套结构体时 assert.Equal 显示 “different lengths” 或字段乱序
Go 的 struct 比较默认逐字段、按定义顺序比,但如果你用 json.Unmarshal 解析后直接 assert,很可能因字段 tag(如 json:"id,string")导致底层类型不一致,或者 map 键顺序不同引发误判。
更稳妥的方式不是靠 Equal 的“看起来一样”,而是明确关注哪些字段必须一致。
- 对简单结构体,用
assert.EqualValues忽略底层类型差异(比如 int vs int64) - 对含 map、slice 或指针的结构体,优先用
assert.JSONEq(需先json.Marshal两边)或cmp.Diff(需引入github.com/google/go-cmp/cmp) - 不要依赖打印出来的 diff 字符串顺序——
map遍历无序是语言特性,断言前先sortkey 或转成有序 slice 再比
最容易被忽略的是:struct 字段未导出(小写开头),json 包和 reflect.DeepEqual 都无法访问,assert.Equal 会当成零值比较。测之前先确认字段首字母大写。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











