讲师中心 微信公众号
AI工具推荐 视频效率加速

如何使用Golang进行数据库测试_Golang数据库单元测试技巧

胖宇小哥_7128

胖宇小哥_7128

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

|

874人浏览过

|

来源于php中文网

原创

testify/mock 不识别 sql.ErrNoRows 是因它只返回显式 Return() 的值,故需手动 .Return(nil, sql.ErrNoRows);判断时应使用 errors.Is(err, sql.ErrNoRows) 而非 ==。

如何使用golang进行数据库测试_golang数据库单元测试技巧

用 testify/mock 模拟数据库驱动时,为什么总报 sql.ErrNoRows 不生效?

因为 testify/mock 默认不识别 sql.ErrNoRows 这类标准错误,它只认你显式 Return() 的值。如果你在 mock 方法里写 .Return(nil, sql.ErrNoRows),调用方拿到的确实是这个错误;但若漏掉这步、或误写成 .Return(nil, nil),下游逻辑就收不到预期错误。

实操建议:

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

  • 所有返回 error 的 mock 方法,必须显式 Return(..., sql.ErrNoRows) 或 Return(..., errors.New("xxx")),不能依赖默认值
  • 检查被测函数是否用 errors.Is(err, sql.ErrNoRows) 判断,而不是 err == sql.ErrNoRows —— 后者在 mock 场景下容易失败
  • 如果用的是 database/sql 原生接口(如 *sql.Rows),mock 时需额外实现 Next() 和 Scan() 行为,否则 rows.Next() 可能永远返回 true

本地跑测试时连不上 localhost:5432,该不该起 Docker Postgres?

应该,但别在每个测试里 docker run 一次。临时容器启动慢、端口冲突、残留数据都会让测试不可靠。

实操建议:

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

  • 用 testcontainers-go 管理生命周期:在 TestMain 中统一启停,避免重复创建
  • 连接字符串用 container.ConnectionString(ctx) 动态获取,不硬编码 localhost:5432
  • 每次测试前用 TRUNCATE TABLE ... RESTART IDENTITY CASCADE 清库,比删库重建快,也避免迁移脚本重复执行
  • 如果只是验证 SQL 语法或简单 CRUD,优先用 sqlite 内存模式("sqlite://:memory:"),启动零延迟,适合快速反馈

sqlmock 报错 there is no expectation for this query 怎么定位?

说明你执行了一条没被 ExpectQuery() 或 ExpectExec() 捕获的 SQL —— 很可能是日志、健康检查、或 ORM 自动生成的隐式语句(比如 GORM 的 SELECT 1 心跳查询)。

Workspace Git Setup
Workspace Git Setup

一键在任意工作目录中设置 Git 跟踪,并附带安全为重点的 .gitignore(包括凭证、TLS/SSH 私钥、令牌、运行时缓存和 PID 等)

下载

实操建议:

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

  • 启用 sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual),关闭模糊匹配,让报错更准
  • 在测试 setup 里加 mock.ExpectQuery("SELECT 1").WillReturnRows(sqlmock.NewRows([]string{"1"})) 拦截心跳
  • 用 mock.ExpectationsWereMet() 放在 defer 里,确保所有期望都被触发,避免漏断言
  • 如果用 GORM,记得关掉自动迁移:gorm.Config{SkipDefaultTransaction: true, DisableForeignKeyConstraintWhenMigrating: true}

测试中用 time.Now() 导致时间相关逻辑不一致怎么办?

直接调用 time.Now() 会让测试依赖系统时钟,尤其涉及过期判断、定时任务模拟时,结果不可控。

实操建议:

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

  • 把时间获取封装成可注入的函数变量,例如 var Now = time.Now,测试时替换为固定时间
  • 使用 github.com/benbjohnson/clock:构造 clock.NewMock(),然后传给 DAO 层,调用 clk.Add(24 * time.Hour) 快进时间
  • 数据库字段如果是 TIMESTAMP WITH TIME ZONE,测试插入时别用 time.Now().UTC(),改用 clk.Now().UTC() 保持时钟源一致

测试里最常被忽略的,是事务隔离级别和自动提交行为。PostgreSQL 默认 READ COMMITTED,但 sqlmock 不模拟隔离,而 testcontainers 里的真实 DB 又可能因并发测试相互干扰 —— 这类问题往往要到 CI 环境才暴露。

热门AI工具

更多
VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

小橡皮AI

一款AI工具,主要用于小橡皮一键去AI味,将机器味重的内容改得更有活人感,防止因为 AI 内容被平台打上 AI 标签,以及限流,适合需要提升相关任务效率的用户。

相关专题

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

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

519

2024.02.23

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

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

616

2024.02.23

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

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

1216

2024.02.23

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

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

791

2024.03.05

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

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

1786

2024.05.21

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

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

5054

2025.06.09

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

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

2334

2025.06.10

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

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

4226

2025.06.17

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

100

2026.10.28

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
vscode手册
vscode手册

共0课时 | 0人学习

Git 教程
Git 教程

共21课时 | 8.1万人学习

Git版本控制工具
Git版本控制工具

共8课时 | 1.9万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn