亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使用 gorm 進行單元測試

如何使用 gorm 進行單元測試

Go
侃侃無極 2022-10-04 16:14:19
我是新來的和.在我的項目中,我正在使用和連接數據庫。Gounit testGogormmysql我的查詢是如何對我的代碼進行單元測試的:main_test:package mainimport (    "log"    "os"    "testing"    "github.com/jinzhu/gorm"    _ "github.com/jinzhu/gorm/dialects/mysql")func TestinitDB(m *testing.M) {    dataSourceName := "root:@tcp(localhost:3306)/?parseTime=True"    db, err := gorm.Open("mysql", dataSourceName)    if err != nil {        log.Fatal("failed to connect database")    }    //db.Exec("CREATE DATABASE test")    db.LogMode(true)    db.Exec("USE test111")    os.Exit(m.Run())}請幫我寫單元測試文件
查看完整描述

2 回答

?
慕哥6287543

TA貢獻1831條經驗 獲得超10個贊

“如何進行單元測試”是一個非常廣泛的問題,因為它取決于你想要測試什么。在您的示例中,您正在處理與數據庫的遠程連接,這通常是在單元測試中被嘲笑的東西。目前尚不清楚這是否是您要尋找的,也不是必需的。通過看到你使用不同的數據庫,我希望其意圖不是嘲笑。


首先看看這篇文章,它已經回答了你關于TestMain和打算如何工作的問題。testing.M


您的代碼當前所做的(如果您的測試名稱正確命名)是在其他測試周圍添加一個方法來執行設置和拆卸,但是您沒有任何其他測試來使用此設置和拆卸,因此您將獲得結果。TestMainno tests to run


這不是你問題的一部分,但我建議盡量避免,直到你對測試Go代碼有信心。使用和測試單獨的單元可能更容易理解。你可以通過調用你的測試并讓初始值設定項接受一個參數來實現幾乎相同的事情。testing.Mtesting.TinitDB()


func initDB(dbToUse string) {

    // ...

    db.Exec("USE "+dbToUse)

}

然后,您將從主文件和測試中調用。您可以在 pkg.go.dev/testing 閱讀有關 Go 的測試包的信息,您還可以在其中找到 和 之間的差異。initDB("test")initDB("test111")testing.Ttesting.M


下面是一個簡短的示例,其中包含一些基本測試,這些測試不需要任何設置或拆卸,而是使用 代替 。testing.Ttesting.M


主要.go


package main


import "fmt"


func main() {

    fmt.Println(add(1, 2))

}


func add(a, b int) int {

    return a + b

}

main_test


package main


import "testing"


func TestAdd(t *testing.T) {

    t.Run("add 2 + 2", func(t *testing.T) {

        want := 4


        // Call the function you want to test.

        got := add(2, 2)


        // Assert that you got your expected response

        if got != want {

            t.Fail()

        }

    })

}

此測試將測試您的方法,并確保它在作為參數傳遞時返回正確的值。使用 是可選的,但它會為您創建一個子測試,這使得讀取輸出更容易一些。add2, 2t.Run


由于在包級別進行測試,因此,如果不以遞歸方式使用三點格式(包括每個包),則需要指定要測試的包。


若要運行上述示例中的測試,請指定包和詳細輸出。-v


$ go test ./ -v

=== RUN   TestAdd

=== RUN   TestAdd/add_2_+_2

--- PASS: TestAdd (0.00s)

    --- PASS: TestAdd/add_2_+_2 (0.00s)

PASS

ok      x       (cached)

圍繞這個主題還有很多東西需要學習,比如測試框架和測試模式。例如,測試框架testify可以幫助您進行斷言,并在測試失敗時打印出漂亮的輸出,并且表驅動的測試是Go中非常常見的模式。


您還在編寫HTTP服務器,該服務器通常需要額外的測試設置才能正確測試。幸運的是,標準庫中的包帶有一個名為httptest的子包,它可以幫助您記錄外部請求或為外部請求啟動本地服務器。還可以通過使用手動構造的請求直接調用處理程序來測試處理程序。http


它看起來像這樣。


func TestSomeHandler(t *testing.T) {

    // Create a request to pass to our handler. We don't have any query parameters for now, so we'll

    // pass 'nil' as the third parameter.

    req, err := http.NewRequest("GET", "/some-endpoint", nil)

    if err != nil {

        t.Fatal(err)

    }


    // We create a ResponseRecorder (which satisfies http.ResponseWriter) to record the response.

    rr := httptest.NewRecorder()

    handler := http.HandlerFunc(SomeHandler)


    // Our handlers satisfy http.Handler, so we can call their ServeHTTP method 

    // directly and pass in our Request and ResponseRecorder.

    handler.ServeHTTP(rr, req)


    // Check the status code is what we expect.

    if status := rr.Code; status != http.StatusOK {

        t.Errorf("handler returned wrong status code: got %v want %v",

            status, http.StatusOK)

    }

現在,測試一些代碼。我們可以運行 init 方法,并使用響應記錄器調用您的任何服務。


package main


import (

    "encoding/json"

    "net/http"

    "net/http/httptest"

    "testing"

)


func TestGetAllJobs(t *testing.T) {

    // Initialize the DB

    initDB("test111")


    req, err := http.NewRequest("GET", "/GetAllJobs", nil)

    if err != nil {

        t.Fatal(err)

    }


    rr := httptest.NewRecorder()

    handler := http.HandlerFunc(GetAllJobs)


    handler.ServeHTTP(rr, req)


    // Check the status code is what we expect.

    if status := rr.Code; status != http.StatusOK {

        t.Errorf("handler returned wrong status code: got %v want %v",

            status, http.StatusOK)

    }


    var response []Jobs

    if err := json.Unmarshal(rr.Body.Bytes(), &response); err != nil {

        t.Errorf("got invalid response, expected list of jobs, got: %v", rr.Body.String())

    }


    if len(response) < 1 {

        t.Errorf("expected at least 1 job, got %v", len(response))

    }


    for _, job := range response {

        if job.SourcePath == "" {

            t.Errorf("expected job id %d to  have a source path, was empty", job.JobID)

        }

    }

}


查看完整回答
反對 回復 2022-10-04
?
小怪獸愛吃肉

TA貢獻1852條經驗 獲得超1個贊

你可以使用 go-sqlmock:


    package main


import (

    "database/sql"

    "regexp"

    "testing"


    "gopkg.in/DATA-DOG/go-sqlmock.v1"

    "gorm.io/driver/postgres"

    "gorm.io/gorm"

)


type Student struct {

    //*gorm.Model

    Name string

    ID string

}

type v2Suite struct {

    db      *gorm.DB

    mock    sqlmock.Sqlmock

    student Student

}


func TestGORMV2(t *testing.T) {

    s := &v2Suite{}

    var (

        db  *sql.DB

        err error

    )


    db, s.mock, err = sqlmock.New()

    if err != nil {

        t.Errorf("Failed to open mock sql db, got error: %v", err)

    }


    if db == nil {

        t.Error("mock db is null")

    }


    if s.mock == nil {

        t.Error("sqlmock is null")

    }


    dialector := postgres.New(postgres.Config{

        DSN:                  "sqlmock_db_0",

        DriverName:           "postgres",

        Conn:                 db,

        PreferSimpleProtocol: true,

    })

    s.db, err = gorm.Open(dialector, &gorm.Config{})

    if err != nil {

        t.Errorf("Failed to open gorm v2 db, got error: %v", err)

    }


    if s.db == nil {

        t.Error("gorm db is null")

    }


    s.student = Student{

        ID:   "123456",

        Name: "Test 1",

    }


    defer db.Close()


    s.mock.MatchExpectationsInOrder(false)

    s.mock.ExpectBegin()


    s.mock.ExpectQuery(regexp.QuoteMeta(

        `INSERT INTO "students" ("id","name")

                    VALUES ($1,$2) RETURNING "students"."id"`)).

    WithArgs(s.student.ID, s.student.Name).

    WillReturnRows(sqlmock.NewRows([]string{"id"}).

            AddRow(s.student.ID))


    s.mock.ExpectCommit()


    if err = s.db.Create(&s.student).Error; err != nil {

        t.Errorf("Failed to insert to gorm db, got error: %v", err)

    }


    err = s.mock.ExpectationsWereMet()

    if err != nil {

        t.Errorf("Failed to meet expectations, got error: %v", err)

    }

}



查看完整回答
反對 回復 2022-10-04
  • 2 回答
  • 0 關注
  • 234 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號