diff --git a/app/repository/repository_test.go b/app/repository/repository_test.go new file mode 100644 index 0000000..ae288d8 --- /dev/null +++ b/app/repository/repository_test.go @@ -0,0 +1,99 @@ +package repository + +import ( + "database/sql" + "log" + "regexp" + "testing" + + "github.com/DATA-DOG/go-sqlmock" + "github.com/stretchr/testify/assert" + "gorm.io/driver/postgres" + "gorm.io/gorm" +) + +func NewMockDB() (*sql.DB, *gorm.DB, sqlmock.Sqlmock) { + sqldb, mock, err := sqlmock.New() + if err != nil { + log.Fatalf("An error '%s' was not expected when opening a stub database connection", err) + } + + gormdb, err := gorm.Open(postgres.New(postgres.Config{ + WithoutQuotingCheck: true, + Conn: sqldb, + }), &gorm.Config{}) + + if err != nil { + log.Fatalf("An error '%s' was not expected when opening gorm database", err) + } + + return sqldb, gormdb, mock +} + +type MyModel struct { + Id int + Value string + Count int +} + +func (m MyModel) TableName() string { + return "my_models" +} + +type MyModelFilter struct { + Id *int `filterfield:"field=id,operator=EQ"` + Value *string `filterfield:"field=value,operator=EQ"` + Count *int `filterfield:"field=count,operator=GT"` +} + +func TestRepository(t *testing.T) { + t.Run("List with simple filter", func(t *testing.T) { + sqldb, db, mock := NewMockDB() + defer sqldb.Close() + + repo := RepoBase[MyModel]{} + repo.Init(db) + + id := 123 + filter := MyModelFilter{ + Id: &id, + } + + sql := "SELECT * FROM my_models WHERE my_models.id = $1" + mock.ExpectQuery(regexp.QuoteMeta(sql)).WithArgs(id) + + _, err := repo.List(filter) + assert.Nil(t, err) + + if err := mock.ExpectationsWereMet(); err != nil { + t.Errorf("there were unfulfilled expectations: %s", err) + } + }) + + t.Run("List with multiple filter values", func(t *testing.T) { + sqldb, db, mock := NewMockDB() + defer sqldb.Close() + + repo := RepoBase[MyModel]{} + repo.Init(db) + + id := 123 + count := 456 + value := "some value" + filter := MyModelFilter{ + Id: &id, + Value: &value, + Count: &count, + } + + sql := "SELECT * FROM my_models WHERE my_models.id = $1 AND my_models.value = $2 AND my_models.count > $3" + mock.ExpectQuery(regexp.QuoteMeta(sql)).WithArgs(id, value, count) + + _, err := repo.List(filter) + assert.Nil(t, err) + + if err := mock.ExpectationsWereMet(); err != nil { + t.Errorf("there were unfulfilled expectations: %s", err) + } + }) +}