下面由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,fun4
fun1:在该测试文件中的最开始执行一次。
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)}

更多相关文章

  1. 详解Golang中函数作为值与类型
  2. go语言中普通函数与方法的区别是什么?
  3. 详解Go 中方法与函数的区别
  4. 关于golang封装一个bash函数,用于执行bash命令
  5. 总结Golang实现PHP常用函数
  6. PHP扩展之XML操作(三)——XML解析器使用及相关函数
  7. 实例简析XPath串函数和XSLT
  8. XmlTextWriter函数定义与用法汇总
  9. XDocument函数定义与用法汇总

随机推荐

  1. Android 报错处理:Android resource linki
  2. 关于No resource identifier found for a
  3. 如何以编程方式退出android应用程序
  4. android 安装文件例子
  5. android 拖动图片/拖动浮动按钮
  6. 处理Android应用在后台被杀死
  7. 使用AndroidStudio编译NDK的方法及错误解
  8. android : java.lang.NoClassDefFoundErr
  9. 选项卡使用方法二(Android学习随笔十三)
  10. Android studio instant run导致的classN