单元测试:gtest/gt 与接口测试写法
结论:GoFrame 提供 gtest 断言包(gtest.C + Assert 系列)与全链路对象(g.Client 等),配合标准 *_test.go 即可写单元测试与接口测试;涉及 DB 的逻辑务必隔离数据源(独立测试库/事务回滚/mock),保证可重复执行。
一、gtest 常用断言
- gtest.C(t, func(t *testing.T)):组织用例体,内部可用一组 Assert。
- gtest.Assert(expect, actual)、AssertEQ(深度相等)、AssertNE、AssertNil/AssertNotNil、AssertIN 等(完整清单以 gtest 文档为准)。
- 与标准库 testing 完全兼容,直接 go test 运行。
二、测试分层
| 层次 | 测什么 | 关键点 |
|---|---|---|
| 单元测试 | 函数/方法逻辑 | 纯函数最好测,DB 依赖要隔离 |
| 接口测试 | 路由+参数+响应 | 起测试 Server,用 g.Client 发请求 |
| 集成/契约 | 多服务协作 | 独立环境、可控数据 |
代码示例
// 单元测试
func TestSum(t *testing.T) {
gtest.C(t, func(t *testing.T) {
gtest.Assert(Sum(1, 2), 3)
gtest.AssertEQ([]int{1, 2}, []int{1, 2})
})
}
// 接口测试:起独立 Server + Client 请求
func TestHelloAPI(t *testing.T) {
s := g.Server()
s.SetPort(18099) // 测试专用端口,避免污染
s.BindHandler("GET:/hello", func(r *ghttp.Request) {
r.Response.Write("hi")
})
s.Start()
defer s.Shutdown()
gtest.C(t, func(t *testing.T) {
resp, err := g.Client().Get(ctx, "http://127.0.0.1:18099/hello")
gtest.Assert(err, nil)
gtest.Assert(resp.ReadAllString(), "hi")
})
}
常见追问 / 记忆点
- 追问:测试里访问数据库怎么保证幂等?→ 用独立测试库,或包在事务中回滚,或 mock dao 层,禁止污染共享数据。
- 追问:接口测试为什么不直接用线上端口?→ 用独立 Server + 随机/专用端口,避免与本地服务冲突。
- 记忆点:gtest.C 组织用例、Assert 全家桶断言、g.Client 打接口;DB 依赖必须隔离。