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?
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