

新闻资讯
技术学院Go单元测试需写Test开头、*testing.T参数的函数,用t.Run组织子测试、t.Errorf报告失败,配合go test运行;测试文件名以_test.go结尾且与被测代码同包。
在 Go 中用 testing 包写单元测试,核心是写以 Test 开头、参数为 *testing.T 的函数,然后用 t.Run 组织子测试、t.Errorf 报告失败,配合 go test 运行验证逻辑是否符合预期。
假设你有一个计算两个整数最大值的函数:
func Max(a, b int) int {
if a > b {
return a
}
return b
}
对应测试文件(如 max_test.go)中这样写:
func TestMax(t *testing.T) {
tests := []struct {
name string
a, b int
want int
}{
{"positive", 3, 5, 5},
{"equal", 4, 4, 4},
{"negative", -2, -7, -2},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := Max(tt.a, tt.b)
if got != tt.want {
t.Errorf("Max(%d, %d) = %d, want %d", tt.a, tt.b, got, tt.want)
}
})
}
}
_test.go 结尾,且与被测代码在同一包内t.Run 支持命名子测试,便于定位失败用例,也支持并行(加 t.Parallel())真实逻辑常涉及空值、零值、错误返回等。比如一个解析 JSON 字符串的函数:
func ParseUser(s string) (*User, error) {
var u User
if err := json.Unmarshal([]byte(s), &u); err != nil {
return nil, fmt.Errorf("parse user: %w", err)
}
return &u, nil
}
测试要覆盖成功、空字符串、非法 JSON、字段缺失等情况:
ParseUser("") 应返回非 nil errorParseUser("{invalid") 同样应报错,且错误信息包含预期前缀if err != nil + t.Error 或 assert.ErrorContains(需引入 github.com/stretchr/testify)判断错误内容如果函数依赖外部调用(如 HTTP 请求、数据库查询),不能在单元测试中真实发起网络请求。推荐做法是抽象接口、注入依赖:
type Fetcher interface {
Get(url string) ([]byte, error)
}
func DownloadAndParse(f Fetcher, url string) (string, error) {
data, err := f.Get(url)
if err != nil {
return "", err
}
return strings.TrimSpace(string(data)), nil
}
测试时传入一个内存实现:
type mockFetcher struct {
data []byte
err error
}
func (m mockFetcher) Get(_ string) ([]byte, error) {
return m.data, m.err
}
func TestDownloadAndParse(t *testing.T) {
t.Run("success", func(t *testing.T) {
got, err := DownloadAndParse(mockFetcher{data: []byte(" hello ")}, "http://x")
if err != nil || got != "hello" {
t.Errorf("unexpected result: %v, %v", got, err)
}
})
t.Run("fetch error", func(t *testing.T) {
_, err := DownloadAndParse(mockFetc
her{err: errors.New("timeout")}, "http://x")
if err == nil {
t.Error("expected error, got nil")
}
})
}
http.Get,而是通过接口接收行为,测试更可控、更快、无副作用使用标准命令快速验证:
go test:运行当前目录所有测试go test -v:显示每个测试名称和日志(t.Log 输出可见)go test -run=^TestMax$:只运行指定测试函数go test -cover:查看测试覆盖率(建议配合 -coverprofile=c.out && go tool cover -html=c.out 生成可视化报告)t.Fatal 或 t.Fatalf 遇错终止当前子测试,避免后续断言干扰判断