DB mock using sqlmock not working for testing Gin/GORM API?

1k Views Asked by At

I've an API written using Gin that uses GORM for ORM. The API works perfectly fine when using a real DB and accessing the API URL from the web browser. But I can't get a mocked unit test to pass:

func TestRespForGetUsersHandlerWithSomeUsers(t *testing.T) {
    db, mock, err := sqlmock.New()
    if err != nil {
        t.Fatal("can't create mock db")
    }
    defer db.Close()

    sqlmock.NewRows(
        []string{"id", "name", "username"},
    ).
        AddRow(1, "Abhishek Kumar", "abhishek")

    w := httptest.NewRecord()
    c, _ := gin.CreateTestContext(w)

    postgresDB := postgres.New(postgres.Config{Conn: db})
    gormDB, err := gorm.Open(postgresDB, &gorm.Config{})
    if err != nil {
        t.Fatal("can't create gormDB")
    }

    api.GetUsersWrapper(gormDB)(c)

    if w.Code != http.StatusOK {
        t.Errorf("Expected status code to be %d but got %d", http.StatusOK, w.Code)
    }

    var got []models.User
    if err := json.Unmarshal(w.Body.Bytes(), &got); err != nil {
        t.Fatalf("Can't unmarshal response body: %s", err)
    }

    if len(got) != 1 {
        t.Errorf("Expected response to be 1 item but got %d items", len(got))
    }
}

The last if-statement gets triggered. The length of got is actually 0. However, if I try calling the API endpoint associated with GetUsersWrapper from a browser (while the server is using a real DB), everything works as expected.

I suspect that either sqlmock.NewRows is not creating the rows such that it'll be visible to gormDB or I'm not testing the response from GetUsersWrapper properly. How can I unit test a gin API correctly?

1

There are 1 best solutions below

0
On

If you're willing to try an alternate approach, you can unit test your gin APIs using keploy. It's open-source and also supports GORM.

https://github.com/keploy/keploy