0

0

如何使用Golang编写单元测试_Golang testing包单元测试示例

P粉602998670

P粉602998670

发布时间:2026-01-02 09:48:09

|

432人浏览过

|

来源于php中文网

原创

Go单元测试需满足文件名以_test.go结尾、函数名以Test开头、参数为*testing.T;go test默认只运行当前目录测试,-run支持正则匹配;应避免log.Fatal/os.Exit,改用t.Fatal/t.Error;推荐表驱动测试与接口抽象解耦外部依赖。

如何使用golang编写单元测试_golang testing包单元测试示例

如何用 go test 运行最简单元测试

Go 的单元测试不需要额外框架,只要文件名以 _test.go 结尾、函数名以 Test 开头、参数为 *testing.T,就能被 go test 自动识别。不满足任一条件,测试就不会执行。

  • go test 默认只运行当前目录下的 *_test.go 文件,不会递归子目录
  • 测试函数必须是导出的(首字母大写),但名字本身不用导出 —— TestAdd 合法,testAdd 会被忽略
  • 若想只跑某个测试,用 go test -run=TestAdd-run 后跟的是正则匹配名,不是函数全名

testing.T 的常见误用:别在测试里用 log.Fatalos.Exit

测试中调用 log.Fatalpanicos.Exit(1) 会导致整个测试进程退出,后续测试全部中断,且 go test 会报 exit status 1,掩盖真实失败原因。

  • 正确做法是调用 t.Fatalt.Errorf + t.FailNow(),它们只终止当前测试函数,不影响其他测试
  • t.Error 记录错误但继续执行,适合检查多个断言;t.Fatal 遇错即停,适合前置条件校验(如初始化失败)
  • 如果被测函数内部调用了 os.Exit(比如 CLI 工具),需通过接口抽象或构建可替换的 os.Exit 函数变量来解耦,否则无法测试

表驱动测试怎么写才不重复又易维护

Go 社区推荐用结构体切片定义测试用例,避免大量复制粘贴的 TestXxx 函数。关键在于把输入、期望输出、描述聚合成一个数据项,再用循环统一执行断言。

func TestParseDuration(t *testing.T) {
    cases := []struct {
        name     string
        input    string
        expected time.Duration
        wantErr  bool
    }{
        {"zero", "0s", 0, false},
        {"seconds", "30s", 30 * time.Second, false},
        {"invalid", "1y", 0, true},
    }
    for _, tc := range cases {
        t.Run(tc.name, func(t *testing.T) {
            got, err := time.ParseDuration(tc.input)
            if tc.wantErr {
                if err == nil {
                    t.Fatal("expected error, got nil")
                }
                return
            }
            if err != nil {
                t.Fatalf("unexpected error: %v", err)
            }
            if got != tc.expected {
                t.Errorf("ParseDuration(%q) = %v, want %v", tc.input, got, tc.expected)
            }
        })
    }
}
  • t.Run 创建子测试,让每个用例独立计时、独立失败,输出带名字(如 --- FAIL: TestParseDuration/seconds
  • 结构体字段名要语义清晰,name 必须有,否则子测试名是空字符串,调试困难
  • 不要在循环里直接用 tc 变量做闭包 —— Go 中循环变量复用,所有 goroutine 或延迟函数会看到最后一个值;必须用 tc := tc 显式拷贝

测试依赖外部服务?用接口+模拟(mock)而不是真实调用

测试不应该依赖数据库、HTTP 服务或文件系统。真实 I/O 不仅慢、不稳定,还会让测试变成集成测试。Go 推崇“依赖倒置”:把具体实现抽成接口,测试时传入内存实现。

arXiv Xplorer
arXiv Xplorer

ArXiv 语义搜索引擎,帮您快速轻松的查找,保存和下载arXiv文章。

下载

立即学习go语言免费学习笔记(深入)”;

  • 例如 HTTP 客户端,不要直接用 http.DefaultClient,而是定义 type HTTPDoer interface { Do(*http.Request) (*http.Response, error) }
  • 测试时传入自定义类型,Do 方法返回预设响应,完全绕过网络
  • 标准库类型(如 *sql.DB)也一样:定义 Querier 接口,只暴露 QueryRow 等方法,测试时用内存 map 模拟结果
  • 避免使用第三方 mock 库(如 gomock),多数场景纯 Go 就够用;mock 库增加编译依赖和学习成本,且容易过度模拟

测试最难的不是写断言,而是识别哪些逻辑该被隔离、哪些状态需要重置。比如全局变量、单例、时间相关代码(time.Now())、随机数生成器(rand.Intn)——这些都得通过参数注入或接口抽象才能可控。没做这一步,测试就只是“能跑”,不是“可信”。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

174

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

225

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

335

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

206

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

388

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

194

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

189

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

191

2025.06.17

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

74

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 3.2万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号