Skip to Content

Test Utilities

The testutil package provides testing utilities for Gofasta applications, including test database setup using testcontainers-go  with PostgreSQL, automatic migration, and cleanup.

Import

import "github.com/gofastadev/gofasta/pkg/testutil/testdb"

Key Functions

Database Helpers

FunctionSignatureDescription
SetupTestDBfunc SetupTestDB(t *testing.T) *gorm.DBSpins up a PostgreSQL container, runs migrations, and returns a connected *gorm.DB
RunMigrationsfunc RunMigrations(db *gorm.DB) errorApplies base SQL migrations to the test database

Usage

Integration Test with Test Database

SetupTestDB starts a PostgreSQL container using testcontainers, runs base migrations, and returns a *gorm.DB. The container is automatically cleaned up when the test finishes via t.Cleanup.

func TestUserRepository_Create(t *testing.T) { db := testdb.SetupTestDB(t) // Auto-migrate your models db.AutoMigrate(&User{}) repo := NewUserRepository(db) user := &User{ Name: "Jane Doe", Email: "jane@example.com", Role: "editor", } err := repo.Create(context.Background(), user) assert.NoError(t, err) assert.NotEmpty(t, user.ID) // Verify the record exists var found User db.First(&found, "email = ?", "jane@example.com") assert.Equal(t, "editor", found.Role) }

Base Migrations

SetupTestDB automatically runs the following base migrations:

  • Creates the citext extension
  • Creates an update_updated_at_column() trigger function
  • Creates a prevent_delete_non_deletable() trigger function
  • Creates an increment_record_version() trigger function

These match the trigger functions that gofasta-generated models expect (updated_at maintenance, soft-delete guards, record versioning). You then add your own model migrations with db.AutoMigrate(...).

HTTP Integration Test

func TestUserController_Create(t *testing.T) { db := testdb.SetupTestDB(t) db.AutoMigrate(&User{}) handler := setupRouter(db) // your router setup function req := httptest.NewRequest(http.MethodPost, "/api/users", strings.NewReader(`{ "name": "Jane Doe", "email": "jane@example.com", "role": "editor" }`)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+testToken) rec := httptest.NewRecorder() handler.ServeHTTP(rec, req) assert.Equal(t, http.StatusCreated, rec.Code) var found User db.First(&found, "email = ?", "jane@example.com") assert.Equal(t, "Jane Doe", found.Name) }

Table-Driven Tests

func TestUserController_GetUser(t *testing.T) { db := testdb.SetupTestDB(t) db.AutoMigrate(&User{}) handler := setupRouter(db) tests := []struct { name string userID string wantStatus int }{ {"existing user", "valid-uuid", http.StatusOK}, {"non-existing user", "missing-uuid", http.StatusNotFound}, {"invalid uuid", "not-a-uuid", http.StatusBadRequest}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { req := httptest.NewRequest(http.MethodGet, "/api/users/"+tt.userID, nil) req.Header.Set("Authorization", "Bearer "+testToken) rec := httptest.NewRecorder() handler.ServeHTTP(rec, req) assert.Equal(t, tt.wantStatus, rec.Code) }) } }
  • Config — Test database configuration
  • Auth — JWT token generation for test requests
  • Models — Models used in test database setup
Last updated on