免费观看又色又爽又黄的小说免费_美女福利视频国产片_亚洲欧美精品_美国一级大黄大色毛片

go單元測試的方法有哪些

本篇內(nèi)容介紹了“go單元測試的方法有哪些”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!

創(chuàng)新互聯(lián)是一家網(wǎng)站設(shè)計制作、成都網(wǎng)站建設(shè),提供網(wǎng)頁設(shè)計,網(wǎng)站設(shè)計,網(wǎng)站制作,建網(wǎng)站,按需設(shè)計網(wǎng)站,網(wǎng)站開發(fā)公司,從2013年成立是互聯(lián)行業(yè)建設(shè)者,服務(wù)者。以提升客戶品牌價值為核心業(yè)務(wù),全程參與項目的網(wǎng)站策劃設(shè)計制作,前端開發(fā),后臺程序制作以及后期項目運營并提出專業(yè)建議和思路。

1.gomock

gomock模擬對象的方式是讓用戶聲明一個接口,然后使用gomock提供的mockgen工具生成mock對象代碼。要模擬(mock)被測試代碼的依賴對象時候,即可使用mock出來的對象來模擬和記錄依賴對象的各種行為:比如最常用的返回值,調(diào)用次數(shù)等等。文字敘述有點抽象,直接上代碼:

go單元測試的方法有哪些

dick.go中DickFunc依賴外部對象OutterObj,本示例就是說明如何使用gomock框架控制所依賴的對象。

func DickFunc( outterObj MockInterface,para int)(result int){
    fmt.Println("This init DickFunc")
    fmt.Println("call outter.func:")

    return outterObj.OutterFunc(para)
}

mockgen工具命令是:

mockgen -source {source_file}.go -destination {dest_file}.go

比如,本示例即是:

mockgen -source src_mock.go -destination dst_mock.go

執(zhí)行完后,可在同目錄下找到生成的dst_mock.go文件,可以看到mockgen工具也實現(xiàn)了接口:

go單元測試的方法有哪些

在本示例中只簡單的更改了返回值,拋磚引玉:

func TestDickFunc(t *testing.T ){
   mockCtrl := gomock.NewController(t)
//defer mockCtrl.Finish()

   mockObj := dick.NewMockMockInterface(mockCtrl)
   mockObj.EXPECT().OutterFunc(3).Return(10)

   result :=dick.DickFunc(mockObj,3)
   t.Log("resutl:",result)

}

使用go test命令執(zhí)行這個單測 

從結(jié)果看:本來應(yīng)該輸出3,最后輸出就是10,和其他語言mock框架相似,生產(chǎn)出來的Mock對象不用自己去重定義這么麻煩。

2.httpexcept

由于go在網(wǎng)絡(luò)架構(gòu)上的優(yōu)秀封裝,使得go在很多網(wǎng)絡(luò)場景被廣泛使用,而http協(xié)議是其中重要部分,在面對http請求的時候,可以對http的client進行測試,算是mock的特殊應(yīng)用場景。

看一個簡單的示例就輕松的看懂了:

func TestHttp(t *testing.T) {

    handler := FruitServer()

    server := httptest.NewServer(handler)
    defer server.Close()

    e := httpexpect.New(t, server.URL)

    e.GET("/fruits").
        Expect().
        Status(http.StatusOK).JSON().Array().Empty()
}

其中還支持對不同方法(包括Header,Post等)的構(gòu)造以及返回值Json的自定義,更多細節(jié)查看其官網(wǎng)

3.testify

還有一個testify使用起來可以說兼容了《一》中的gocheck和gomock,但是其mock使用稍微有點煩雜,使用繼承tetify.Mock(匿名組合)重新實現(xiàn)需要Mock的接口,在這個接口里使用者自己使用Called(反射實現(xiàn))被Mock的接口。

《單元測試的藝術(shù)》中認為stub和mock最大的區(qū)別就依賴對象是否和被測對象有交互,而從結(jié)果看就是樁對象不會使測試失敗,它只是為被測對象提供依賴的對象,并不改變測試結(jié)果,而mock則會根據(jù)不同的交互測試要求,很可能會更改測試的結(jié)果。說了這么多理論,但其實這兩種方法都不是割裂的,所以gomock框架除了像其名字一樣可以模擬對象以外,還提供了樁對象的功能(stub)。以其實現(xiàn)來說,更像是一個樁對象的注入。但是因為兼容了多個有用的功能,所以其在社區(qū)最為火爆。

具體用法可參考其github主頁

4.go-sqlmock

還有一種比較常見的場景就是和數(shù)據(jù)庫的交互場景,go-sqlmock是sql模擬(Mock)驅(qū)動器,主要用于測試數(shù)據(jù)庫的交互,go-sqlmock提供了完整的事務(wù)的執(zhí)行測試框架,最新的版本(16.11.02)還支持prepare參數(shù)化提交和執(zhí)行的Mock方案。

比如有這樣的被測函數(shù):

func recordStats(db *sql.DB, userID, productID int64) (err error) {
    tx, err := db.Begin()
    if err != nil {
        return
    }

    defer func() {
        switch err {
        case nil:
            err = tx.Commit()
        default:
            tx.Rollback()
        }
    }()

    if _, err = tx.Exec("UPDATE products SET views = views + 1"); err != nil {
        return
    }
    if _, err = tx.Exec("INSERT INTO product_viewers (user_id, product_id) VALUES (?, ?)", userID, productID); err != nil {
        return
    }
    return
}

func main() {

    db, err := sql.Open("MySQL", "root@/root")
    if err != nil {
        panic(err)
    }
    defer db.Close()

    if err = recordStats(db, 1 , 5 ); err != nil {
        panic(err)
    }
}

單測時:

func TestShouldUpdateStats(t *testing.T) {
    db, mock, err := sqlmock.New()
    if err != nil {
        t.Fatalf("mock error: '%s' ", err)
    }
    defer db.Close()

    mock.ExpectBegin()
    mock.ExpectExec("UPDATE products").WillReturnResult(sqlmock.NewResult(1, 1))
    mock.ExpectExec("INSERT INTO product_viewers")
          .WithArgs(2, 3)
          .WillReturnResult(sqlmock.NewResult(1, 1))
    mock.ExpectCommit()

    if err = recordStats(db, 2, 3); err != nil {
        t.Errorf("exe error: %s", err)
    }

    if err := mock.ExpectationsWereMet(); err != nil {
        t.Errorf("not implements: %s", err)
    }
}

//測試回滾
func TestShouldRollbackStatUpdatesOnFailure(t *testing.T) {
    db, mock, err := sqlmock.New()
    if err != nil {
        t.Fatalf("mock error: '%s'", err)
    }
    defer db.Close()

    mock.ExpectBegin()
    mock.ExpectExec("UPDATE products").WillReturnResult(sqlmock.NewResult(1, 1))
    mock.ExpectExec("INSERT INTO product_viewers")
           .WithArgs(2, 3)
           .WillReturnError(fmt.Errorf("some error"))
    mock.ExpectRollback()

    // 執(zhí)行被測方法,有錯
    if err = recordStats(db, 2, 3); err == nil {
        t.Errorf("not error")
    }

    // 執(zhí)行被測方法,mock對象
    if err := mock.ExpectationsWereMet(); err != nil {
        t.Errorf("not implements: %s", err)
    }
}

“go單元測試的方法有哪些”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

新聞名稱:go單元測試的方法有哪些
當前鏈接:http://newbst.com/article46/jhcieg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供云服務(wù)器品牌網(wǎng)站制作定制開發(fā)靜態(tài)網(wǎng)站網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都seo排名網(wǎng)站優(yōu)化