Documentation
¶
Overview ¶
Package dbtest provides lightweight test helpers for code built on github.com/brpaz/lib-go/db.
Transactions ¶
WithTx opens a transaction on an existing *gorm.DB and rolls it back when the test ends, giving each test a clean slate:
func TestCreateUser(t *testing.T) {
tx := dbtest.WithTx(t, gormDB)
svc := user.NewService(tx)
// any writes are rolled back when t ends
}
PostgreSQL ¶
NewPostgresContainer starts an ephemeral PostgreSQL instance via Testcontainers:
func TestSomething(t *testing.T) {
pg, err := dbtest.NewPostgresContainer(context.Background())
require.NoError(t, err)
pg.Cleanup(t) // terminates the container when t ends
}
For a package-scoped container shared across all tests, set a package-level variable from TestMain and use PostgresContainer.NewIsolatedDB per test:
var testPG *dbtest.PostgresContainer
func TestMain(m *testing.M) {
var err error
testPG, err = dbtest.NewPostgresContainer(context.Background())
if err != nil { log.Fatal(err) }
code := m.Run()
testPG.Terminate(context.Background())
os.Exit(code)
}
func TestSomething(t *testing.T) {
db := testPG.NewIsolatedDB(t) // fresh database, dropped on test end
}
Use MigratePostgres to apply goose SQL migrations to a database before running tests against it (the container's default database, or one returned by PostgresContainer.NewIsolatedDB):
//go:embed migrations/*.sql var migrationsFS embed.FS pg, err := dbtest.NewPostgresContainer(context.Background()) require.NoError(t, err) require.NoError(t, dbtest.MigratePostgres(context.Background(), pg.DSN, migrationsFS))
SQLite ¶
NewSQLite opens a fresh, isolated in-memory SQLite database — no Docker required. Each call gets its own database, safe for parallel tests:
func TestSomething(t *testing.T) {
gdb, err := dbtest.NewSQLite()
require.NoError(t, err)
}
Pass [WithSQLiteMigrations] to apply goose SQL migrations before NewSQLite returns:
//go:embed migrations/*.sql var migrationsFS embed.FS gdb, err := dbtest.NewSQLite(dbtest.WithSQLiteMigrations(migrationsFS))
Index ¶
- func MigratePostgres(ctx context.Context, dsn string, fsys fs.FS) error
- func NewSQLite(opts ...SQLiteOption) (*gorm.DB, error)
- func WithTx(t *testing.T, db *gorm.DB) *gorm.DB
- type PostgresContainer
- type PostgresOption
- func WithPostgresContainerOptions(opts ...testcontainers.ContainerCustomizer) PostgresOption
- func WithPostgresDatabase(name string) PostgresOption
- func WithPostgresImage(image string) PostgresOption
- func WithPostgresPassword(password string) PostgresOption
- func WithPostgresUsername(name string) PostgresOption
- type PostgresOptions
- type SQLiteOption
- type SQLiteOptions
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func MigratePostgres ¶
MigratePostgres opens a raw *sql.DB connection to dsn and applies the goose SQL migrations from fsys using the postgres dialect.
Use this against a PostgresContainer.DSN (or a database returned by PostgresContainer.NewIsolatedDB) to prepare a schema before running tests.
func NewSQLite ¶
func NewSQLite(opts ...SQLiteOption) (*gorm.DB, error)
NewSQLite opens a fresh, isolated in-memory SQLite database for use in tests. Each call returns its own database, safe for use in parallel tests.
SQLite in-memory databases only persist for as long as a connection is open, so the returned *gorm.DB is configured with a single connection in its pool to keep the schema and data visible across queries.
func WithTx ¶
WithTx opens a database transaction on db and returns it as a *gorm.DB. The transaction is automatically rolled back when t ends, so each test starts with a clean slate without needing to reset or drop tables.
The returned *gorm.DB is a drop-in replacement for a regular *gorm.DB and can be passed directly to application services and repositories under test.
func TestCreateUser(t *testing.T) {
tx := dbtest.WithTx(t, gormDB)
svc := user.NewService(tx)
// any writes are rolled back when t ends
}
Types ¶
type PostgresContainer ¶
type PostgresContainer struct {
DSN string
// contains filtered or unexported fields
}
PostgresContainer wraps a Testcontainers PostgreSQL container for use in tests.
func NewPostgresContainer ¶
func NewPostgresContainer(ctx context.Context, opts ...PostgresOption) (c *PostgresContainer, err error)
NewPostgresContainer starts a PostgreSQL container and returns it. The caller is responsible for terminating it — call PostgresContainer.Cleanup to register automatic termination scoped to a test, or PostgresContainer.Terminate after m.Run() in TestMain.
func (*PostgresContainer) Cleanup ¶
func (c *PostgresContainer) Cleanup(t *testing.T)
Cleanup registers a t.Cleanup hook that terminates the container when t ends. Call this immediately after NewPostgresContainer in per-test usage.
func (*PostgresContainer) NewIsolatedDB ¶
func (c *PostgresContainer) NewIsolatedDB(t *testing.T) *sql.DB
NewIsolatedDB creates a fresh Postgres database on the shared container and returns an open *sql.DB connected to it. The database is dropped when t ends.
Use this in package-scoped container tests to keep each test's schema changes independent without spinning up a new container per test.
func (*PostgresContainer) OpenDB ¶
func (c *PostgresContainer) OpenDB(t *testing.T) *sql.DB
OpenDB opens a *sql.DB connection to the container using the pgx driver. The connection is closed automatically when t ends via t.Cleanup.
func (*PostgresContainer) Terminate ¶
func (c *PostgresContainer) Terminate(ctx context.Context)
Terminate stops the container. Call this after m.Run() returns in TestMain.
type PostgresOption ¶
type PostgresOption func(*PostgresOptions)
PostgresOption is a functional option for NewPostgresContainer.
func WithPostgresContainerOptions ¶
func WithPostgresContainerOptions(opts ...testcontainers.ContainerCustomizer) PostgresOption
WithPostgresContainerOptions appends additional Testcontainers customizers (e.g. custom wait strategies, env vars, mounts) to the container request.
func WithPostgresDatabase ¶
func WithPostgresDatabase(name string) PostgresOption
WithPostgresDatabase overrides the default database name. Defaults to "testdb".
func WithPostgresImage ¶
func WithPostgresImage(image string) PostgresOption
WithPostgresImage overrides the Postgres image used by the container. Defaults to "postgres:18-alpine".
func WithPostgresPassword ¶
func WithPostgresPassword(password string) PostgresOption
WithPostgresPassword overrides the default Postgres password. Defaults to "postgres".
func WithPostgresUsername ¶
func WithPostgresUsername(name string) PostgresOption
WithPostgresUsername overrides the default Postgres username. Defaults to "postgres".
type PostgresOptions ¶
type PostgresOptions struct {
Image string
Database string
Username string
Password string
ContainerOpts []testcontainers.ContainerCustomizer
}
PostgresOptions configures NewPostgresContainer.
type SQLiteOption ¶
type SQLiteOption func(*SQLiteOptions)
SQLiteOption is a functional option for NewSQLite.