使用go优雅地撰写单元测试的方法

小编给大家分享一下使用go优雅地撰写单元测试的方法,希望大家阅读完这篇文章后大所收获,下面让我们一起去探讨吧!

南阳网站制作公司哪家好,找成都创新互联公司!从网页设计、网站建设、微信开发、APP开发、响应式网站开发等网站项目制作,到程序开发,运营维护。成都创新互联公司从2013年成立到现在10年的时间,我们拥有了丰富的建站经验和运维经验,来保证我们的工作的顺利进行。专注于网站建设就选成都创新互联公司

                                                       

背景

刚刚加入一个年轻的小组,代码中的单元测试还没有来得及写,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)}

看完了这篇文章,相信你对使用go优雅地撰写单元测试的方法有了一定的了解,想了解更多相关知识,欢迎关注创新互联行业资讯频道,感谢各位的阅读!


标题名称:使用go优雅地撰写单元测试的方法
文章分享:http://scyanting.com/article/gpeeei.html