add tests for repository
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s

This commit is contained in:
Thomas Peetz
2026-10-06 17:11:42 +02:00
parent 32f3f034eb
commit 980eda29af
9 changed files with 154 additions and 17 deletions
+3 -1
View File
@@ -12,9 +12,11 @@ require (
github.com/google/uuid v1.6.0 github.com/google/uuid v1.6.0
github.com/spf13/cobra v1.10.2 github.com/spf13/cobra v1.10.2
github.com/spf13/viper v1.21.0 github.com/spf13/viper v1.21.0
github.com/stretchr/testify v1.12.1
golang.org/x/crypto v0.57.0 golang.org/x/crypto v0.57.0
golang.org/x/time v0.16.0 golang.org/x/time v0.16.0
gorm.io/driver/postgres v1.6.3 gorm.io/driver/postgres v1.6.3
gorm.io/driver/sqlite v1.6.0
gorm.io/gorm v1.31.2 gorm.io/gorm v1.31.2
resty.dev/v3 v3.0.0-rc.4 resty.dev/v3 v3.0.0-rc.4
) )
@@ -48,6 +50,7 @@ require (
github.com/klauspost/cpuid/v2 v2.4.0 // indirect github.com/klauspost/cpuid/v2 v2.4.0 // indirect
github.com/leodido/go-urn v1.5.0 // indirect github.com/leodido/go-urn v1.5.0 // indirect
github.com/mattn/go-isatty v0.0.24 // indirect github.com/mattn/go-isatty v0.0.24 // indirect
github.com/mattn/go-sqlite3 v1.14.22 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.4.3 // indirect github.com/pelletier/go-toml/v2 v2.4.3 // indirect
@@ -57,7 +60,6 @@ require (
github.com/spf13/afero v1.15.0 // indirect github.com/spf13/afero v1.15.0 // indirect
github.com/spf13/cast v1.10.0 // indirect github.com/spf13/cast v1.10.0 // indirect
github.com/spf13/pflag v1.0.10 // indirect github.com/spf13/pflag v1.0.10 // indirect
github.com/stretchr/testify v1.12.1 // indirect
github.com/subosito/gotenv v1.6.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.3.2 // indirect github.com/ugorji/go/codec v1.3.2 // indirect
+1 -1
View File
@@ -15,7 +15,7 @@ type SportHandler struct {
} }
func (handler *SportHandler) List(c *gin.Context) { func (handler *SportHandler) List(c *gin.Context) {
sports, err := handler.Service.List(c.Request.Context()) sports, _, err := handler.Service.List(c.Request.Context())
if err != nil { if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return return
+15 -1
View File
@@ -3,9 +3,23 @@ package internal
import ( import (
"testing" "testing"
"kontor-api-gin/internal/test/testutils" "kontor-api-gin/internal/tests"
"kontor-api-gin/internal/tests/testutils"
"github.com/stretchr/testify/suite"
"gorm.io/gorm"
) )
var TestDB *gorm.DB
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
testutils.InitializeTestSuite(m) testutils.InitializeTestSuite(m)
} }
func TestRepos(t *testing.T) {
suite.Run(t, new(tests.RepositoryTestSuite))
}
func TestServices(t *testing.T) {
suite.Run(t, new(tests.ServiceTestSuite))
}
+14 -6
View File
@@ -17,13 +17,21 @@ func NewSportRepository(db *gorm.DB) *SportRepository {
return repo return repo
} }
func (repository *SportRepository) FindAll(context context.Context) ([]models.Sport, error) { func (repository *SportRepository) FindAll(page int, limit int, context context.Context) (sports []models.Sport, total int64, err error) {
var sports []models.Sport offset := (page - 1) * limit
result := repository.db.Find(&sports) err = repository.db.
slog.Info("SportRepository#FindAll", "count", result.RowsAffected) Model(&models.Sport{}).
Count(&total).
return sports, nil Limit(limit).
Offset(offset).
Order("id asc").
Find(&sports).Error
if err != nil {
return
}
slog.Info("SportRepository#FindAll", "total", total)
return
} }
func (repository *SportRepository) GetById(context context.Context, id string) (models.Sport, error) { func (repository *SportRepository) GetById(context context.Context, id string) (models.Sport, error) {
+2 -2
View File
@@ -16,9 +16,9 @@ func NewSportService(repo *repository.SportRepository) *SportService {
return service return service
} }
func (service *SportService) List(context context.Context) ([]models.Sport, error) { func (service *SportService) List(context context.Context) ([]models.Sport, int64, error) {
slog.Info("SportService#List") slog.Info("SportService#List")
return service.repository.FindAll(context) return service.repository.FindAll(1, 10, context)
} }
func (service *SportService) Get(context context.Context, id string) (models.Sport, error) { func (service *SportService) Get(context context.Context, id string) (models.Sport, error) {
+65
View File
@@ -0,0 +1,65 @@
package tests
import (
"context"
"kontor-api-gin/internal/models"
"kontor-api-gin/internal/repository"
"log/slog"
"os"
"github.com/stretchr/testify/suite"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
var testDB *gorm.DB
type RepositoryTestSuite struct {
suite.Suite
}
func (suite *RepositoryTestSuite) TestSportFindAll() {
sportRepository := repository.NewSportRepository(testDB)
_, total, err := sportRepository.FindAll(1, 10, context.Background())
suite.Nil(err)
suite.Equal(int64(0), total)
}
// This will run right before the test starts
// and receives the suite and test names as input
func (suite *RepositoryTestSuite) BeforeTest(suiteName, testName string) {
slog.Info("RepositoryTestSuite#BeforeTest", "suiteName", suiteName, "testName", testName)
}
// This will run after test finishes
// and receives the suite and test names as input
func (suite *RepositoryTestSuite) AfterTest(suiteName, testName string) {
slog.Info("RepositoryTestSuite#AfterTest", "suiteName", suiteName, "testName", testName)
}
// This will run before before the tests in the suite are run
func (suite *RepositoryTestSuite) SetupSuite() {
slog.Info("RepositoryTestSuite#SetupSuite")
// Remove existing test db to ensure clean state
os.Remove("test.db")
db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
if err != nil {
panic("failed to connect test database")
}
// Auto-migrate models to ensure schema matches
db.AutoMigrate(&models.Sport{})
testDB = db
}
// This will run before before the tests in the suite are run
func (suite *RepositoryTestSuite) TearDownSuite() {
slog.Info("RepositoryTestSuite#TeardownSuite")
}
// This will run before each test in the suite
func (suite *RepositoryTestSuite) SetupTest() {
slog.Info("RepositoryTestSuite#SetupTest")
}
+45
View File
@@ -0,0 +1,45 @@
package tests
import (
"context"
"kontor-api-gin/internal/models"
"kontor-api-gin/internal/repository"
"kontor-api-gin/internal/service"
"log/slog"
"os"
"github.com/stretchr/testify/suite"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
var testServiceDB *gorm.DB
type ServiceTestSuite struct {
suite.Suite
}
func (suite *ServiceTestSuite) TestSportServiceList() {
sportService := service.NewSportService(repository.NewSportRepository(testServiceDB))
sports, total, err := sportService.List(context.Background())
suite.Nil(err)
suite.Equal(int64(0), total)
suite.Equal(0, len(sports))
}
// This will run before before the tests in the suite are run
func (suite *ServiceTestSuite) SetupSuite() {
slog.Info("RepositoryTestSuite#SetupSuite")
// Remove existing test db to ensure clean state
os.Remove("test.db")
db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
if err != nil {
panic("failed to connect test database")
}
// Auto-migrate models to ensure schema matches
db.AutoMigrate(&models.Sport{})
testServiceDB = db
}
@@ -1,27 +1,29 @@
package testutils package testutils
import ( import (
"log/slog"
"os" "os"
"testing" "testing"
) )
func SetupTestDatabase() { func SetupTestDatabase() {
slog.Info("SetupTestDatabase")
} }
func PatchDatabase() { func PatchDatabase() {
slog.Info("PatchDatabase")
} }
func TearDownTestDatabase() { func TearDownTestDatabase() {
slog.Info("TearDownTestDatabase")
} }
func UnpatchDatabase() { func UnpatchDatabase() {
slog.Info("UnpatchDatabase")
} }
func InitializeTestSuite(m *testing.M) { func InitializeTestSuite(m *testing.M) {
slog.Info("InitializeTestSuite")
// Initialize the test database // Initialize the test database
SetupTestDatabase() SetupTestDatabase()
// Patch the global database.DB to use the TestDB // Patch the global database.DB to use the TestDB
@@ -1,7 +1,8 @@
package helpers package tests
import ( import (
"encoding/json" "encoding/json"
"kontor-api-gin/internal/helpers"
"testing" "testing"
) )
@@ -40,7 +41,7 @@ func TestMultiFormatTimeUnmarshal(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
var m KontorTime var m helpers.KontorTime
err := json.Unmarshal([]byte(tt.input), &m) err := json.Unmarshal([]byte(tt.input), &m)
if (err != nil) != tt.wantErr { if (err != nil) != tt.wantErr {
t.Errorf("UnmarshalJSON() error = %v, wantErr %v", err, tt.wantErr) t.Errorf("UnmarshalJSON() error = %v, wantErr %v", err, tt.wantErr)