如何使用go优雅地撰写单元测试

互联网 20-9-7

下面由golang教程栏目给大家介绍怎么使用go优雅地撰写单元测试,希望对需要的朋友有所帮助!

背景

刚刚加入一个年轻的小组,代码中的单元测试还没有来得及写,leader希望我通过单元测试来熟悉项目的业务逻辑。但是,代码量实在有点多,高效的完成单元测试成为首要目标。

实现原理

单元测试测用的是testify的测试框架,使用起来非常方便,具体的基础使用方法可以参考中文testify博客以及官方文档。

项目中的应用

初始化单元测试

在一个复杂的Web项目中,测试某一模块的功能往往需要先对这一模块所使用到的服务进行初始化,我们将初始化函数以及初始化函数所使用到的参数都放在同一个单元测试包下,例如对MySQL的初始化如下:

package unitTestfunc InitMySQL() error{     return db.Init(constant.MySQLDSN,     constant.MaxIdleConns,     constant.MaxOpenConns,      time.Duration(constant.ConnMaxLifetime)*time.Second,     constant.EnableSqlLog)//其他包中已经封装了初始化函数,在测试包的初始化函数中调用即可}func CloseDB() error{     return db.Close()}

我们在另一个contant包下存放对应的参数:

package constantconstant(     MySQLDSN = "username:password@addresss/db?timeout=5000ms&readTimeout=5s&charset=utf8mb4"     MaxIdleConns = 20     MaxOpenConns = 20     ConnMaxLifetime = 60     EnableSqlLog = true     MerchantID = 6666     SheetID = "SZSWIMTEST"     Operator = "XXXX@XXXX")

进行单元测试

以下以对数据库的操作为例单元测试主要由三部分组成:第一部分为固定写法

type ActionLogRepo struct {     basetest.BaseSuite}

第二部分为对Register进行初始化,Register函数可以传入四个参数fun1,fun2,fun3,fun4fun1:在该测试文件中的最开始执行一次。fun2:在每个单元测试前都执行一次。fun3:在每个单元测试后都执行一次。fun4:在该测试文件中的最终执行一次。根据需求,我们需要在所有单元测试开始前执行一次初始化数据库操作,以及在最后关闭数据库。

func TestActionLogRepo(t *testing.T) {     AgentSuite := new(ActionLogRepo)     var err error     AgentSuite.Register(         func() {             err = unitTest.InitMySQL()         },         nil,         nil,         func() {             err = unitTest.CloseDB()         })     assert.Nil(t,err)     suite.Run(t, AgentSuite)}

第三部分,进行单元测试,我们先在数据库中建立对应的数据,然后调用需要单元测试的函数进行对该数据的操作,之后使用assert对该结果进行验证,最后要记得删除掉单元测试的记录。

func (suite *ActionLogRepo) TestActionLog() {     repo := repository.NewRepository()//获取数据库     actionLog := &model.ActionLogTab{XXXXXX}     err := CreateActionLog(actionLog)//创建测试的数据记录     assert.Nil(suite.T(),err)     logs,count,err := FetchActionLogs(repo,repo.MerchantID,actionLog.SheetID,actionLog.SheetType,1,1)//需要测试的函数     assert.Nil(suite.T(),err)     assert.Equal(suite.T(),logs[0].OperationTime,actionLog.OperationTime)//验证函数的正确性      err = repo.MerchantDB().Delete(actionLog).Error//删除掉测试的数据库记录     assert.Nil(suite.T(),err)}

最终的测试文件结构如下:

package testtype ActionLogRepo struct {     basetest.BaseSuite}func TestActionLogRepo(t *testing.T) {     AgentSuite := new(ActionLogRepo)     var err error     AgentSuite.Register(         func() {             err = unitTest.InitMySQL()         },         nil,         nil,         func() {             err = unitTest.CloseDB()         })     assert.Nil(t,err)     suite.Run(t, AgentSuite)}func (suite *ActionLogRepo) TestActionLog() {     repo := repository.NewRepository()//获取数据库     actionLog := &model.ActionLogTab{XXXXXX}     err := CreateActionLog(actionLog)//创建测试的数据记录     assert.Nil(suite.T(),err)     logs,count,err := FetchActionLogs(repo,repo.MerchantID,actionLog.SheetID,actionLog.SheetType,1,1)//需要测试的函数     assert.Nil(suite.T(),err)     assert.Equal(suite.T(),logs[0].OperationTime,actionLog.OperationTime)//验证函数的正确性      err = repo.MerchantDB().Delete(actionLog).Error//删除掉测试的数据库记录     assert.Nil(suite.T(),err)}

以上就是如何使用go优雅地撰写单元测试的详细内容,更多内容请关注技术你好其它相关文章!

来源链接:
免责声明:
1.资讯内容不构成投资建议,投资者应独立决策并自行承担风险
2.本文版权归属原作所有,仅代表作者本人观点,不代表本站的观点或立场
标签: golang教程
上一篇:php获取远程图片并下载保存到本地的方法分析 下一篇:​教你导入golang.org的包

相关资讯