首頁 >後端開發 >Golang >如何使用go優雅地撰寫單元測試

如何使用go優雅地撰寫單元測試

藏色散人
藏色散人轉載
2020-09-07 09:16:501966瀏覽
##上中對

golang教學專欄為大家一起介紹如何使用go優雅地撰寫測試,希望對需要的朋友有所幫助!

如何使用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)}

以上是如何使用go優雅地撰寫單元測試的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:learnku.com。如有侵權,請聯絡admin@php.cn刪除