mysqltest

package module
v0.0.0-...-af6aa87 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 20, 2025 License: MIT Imports: 8 Imported by: 0

README

mysqltest

Go Reference

A Go library for creating isolated MySQL test databases with automatic cleanup.

Features

  • Isolated Test Databases: Each test gets its own randomly named database and user
  • Automatic Cleanup: Database and user are automatically removed after tests complete
  • Flexible Configuration: Customize MySQL connection settings
  • Easy Setup: Simple API for setting up test databases with initial schema and data

Installation

go get github.com/cybozu-go/mysqltest

Quick Start

package main_test

import (
	"database/sql"
	"net"
	"testing"
	"time"

	"github.com/cybozu-go/mysqltest"
	"github.com/go-sql-driver/mysql"
)

type TodoList struct {
	db *sql.DB
}

func (t *TodoList) Add(item string) error {
	_, err := t.db.Exec("INSERT INTO todos (item) VALUES (?)", item)
	return err
}

func (t *TodoList) List() ([]string, error) {
	rows, err := t.db.Query("SELECT item FROM todos")
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var items []string
	for rows.Next() {
		var item string
		if err := rows.Scan(&item); err != nil {
			return nil, err
		}
		items = append(items, item)
	}
	return items, nil
}

func TestAddTodo(t *testing.T) {
	// Setup
	query1 := "CREATE TABLE todos (" +
		"id INT AUTO_INCREMENT PRIMARY KEY, " +
		"item VARCHAR(255) NOT NULL)"
	query2 := "INSERT INTO todos (item) VALUES ('Buy milk')"

	conn := mysqltest.SetupDatabase(t,
		mysqltest.RootUserCredentials("root", "root"),
		mysqltest.Verbose(),
		mysqltest.ModifyConfig(func(c *mysql.Config) {
			c.Net = "tcp"
			c.Addr = "127.0.0.1:3306"
			c.MultiStatements = true
		}),
		mysqltest.Queries(query1, query2),
	)

	sut := &TodoList{db: conn.DB}

	// Exercise
	err := sut.Add("Walk the dog")
	if err != nil {
		t.Fatal(err)
	}

	// Verify
	actual, err := sut.List()
	if err != nil {
		t.Fatal(err)
	}

	expected := []string{"Buy milk", "Walk the dog"}
	if len(actual) != len(expected) {
		t.Fatalf("expected %d items, got %d", len(expected), len(actual))
	}
	for i := range actual {
		if actual[i] != expected[i] {
			t.Fatalf("unexpected item at index %d: got %q, want %q", i, actual[i], expected[i])
		}
	}
}

Configuration

Configuration Options

You can customize the MySQL connection and test setup using the following options:

RootUserCredentials

Set the MySQL root user credentials for database setup. If not specified, the default credentials are "root"/"root".

conn := mysqltest.SetupDatabase(t,
    mysqltest.RootUserCredentials("admin", "secret123"),
)
PreserveTestDB

Preserve the test database and user after test completion for debugging. By default, test databases and users are automatically cleaned up when tests finish.

conn := mysqltest.SetupDatabase(t,
    mysqltest.PreserveTestDB(), // Database won't be cleaned up
)
Verbose

Enable verbose logging to see MySQL connection details during setup:

conn := mysqltest.SetupDatabase(t,
    mysqltest.Verbose(), // Log connection details
)
ModifyConfig

Customize the underlying MySQL configuration:

conn := mysqltest.SetupDatabase(t,
    mysqltest.ModifyConfig(func(c *mysql.Config) {
        c.Net = "tcp"
        c.Addr = "127.0.0.1:3306"
		c.MultiStatements = true
        c.Timeout = 10 * time.Second
        c.Params = map[string]string{
            "charset": "utf8mb4",
        }
		c.ParseTime = true
    }),
)
Query and Queries

Execute SQL statements after database setup:

// Single query
conn := mysqltest.SetupDatabase(t,
    mysqltest.Query("CREATE TABLE products (id INT PRIMARY KEY, name VARCHAR(255))"),
)

// Multiple queries
conn := mysqltest.SetupDatabase(t,
    mysqltest.Queries(
        "CREATE TABLE products (id INT PRIMARY KEY, name VARCHAR(255))",
        "INSERT INTO products VALUES (1, 'Widget')",
    ),
)

Note: If your queries contain multiple statements separated by semicolons, you must enable MultiStatements:

conn := mysqltest.SetupDatabase(t,
    mysqltest.ModifyConfig(func(c *mysql.Config) {
        c.MultiStatements = true
    }),
    mysqltest.Query("CREATE TABLE t1 (id INT); INSERT INTO t1 VALUES (1);"),
)

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Conn

type Conn struct {
	DB       *sql.DB
	Schema   string
	User     string
	Password string
}

Conn represents a test database connection with credentials and schema information.

func SetupDatabase

func SetupDatabase(t *testing.T, options ...Option) *Conn

SetupDatabase creates a test database with random credentials and returns a connection. It automatically handles cleanup and applies the provided configuration options.

type Option

type Option func(*config)

Option configures the MySQL test setup.

func ModifyConfig

func ModifyConfig(f func(*mysql.Config)) Option

ModifyConfig applies a modification function to the underlying MySQL configuration created by mysql.NewConfig(). Use this to customize connection settings like timeouts or protocol.

Note: Some configuration fields will be overridden by SetupDatabase:

  • Addr is overridden with values from HostEnv and PortEnv environment variables
  • User and Passwd are overridden with RootUserEnv and RootPasswordEnv for root connections, or with randomly generated values for test user connections
  • DBName is overridden with a randomly generated database name for test connections
Example
package main

import (
	"time"

	"github.com/cybozu-go/mysqltest"
	"github.com/go-sql-driver/mysql"
)

func main() {
	mysqltest.ModifyConfig(func(c *mysql.Config) {
		c.Net = "tcp"
		c.MultiStatements = true
		c.Timeout = 30 * time.Second
		c.ReadTimeout = 10 * time.Second
		c.WriteTimeout = 10 * time.Second
	})
}

func PreserveTestDB

func PreserveTestDB() Option

PreserveTestDB controls whether the test database and user are preserved after test completion. By default, the test database and user are automatically cleaned up when the test finishes. When this option is specified, the database and user will remain in MySQL for debugging or manual inspection.

func Queries

func Queries(queries ...string) Option

Queries sets multiple SQL queries to be executed after database setup.

Note: If any of your queries contain multiple statements separated by semicolons, you must enable MultiStatements in the MySQL configuration:

db := mysqltest.SetupDatabase(t,
	mysqltest.ModifyConfig(func(cfg *mysql.Config) {
		cfg.MultiStatements = true
	}),
	mysqltest.Queries(
		"CREATE TABLE t1 (id INT); INSERT INTO t1 VALUES (1);",
		"CREATE TABLE t2 (name VARCHAR(50))",
	))

func Query

func Query(query string) Option

Query sets a single SQL query to be executed after database setup.

Note: If your query contains multiple statements separated by semicolons, you must enable MultiStatements in the MySQL configuration:

db := mysqltest.SetupDatabase(t,
	mysqltest.ModifyConfig(func(cfg *mysql.Config) {
		cfg.MultiStatements = true
	}),
	mysqltest.Query("CREATE TABLE t1 (id INT); INSERT INTO t1 VALUES (1);"))

func RootUserCredentials

func RootUserCredentials(user, password string) Option

RootUserCredentials sets the root user credentials for MySQL connection. If not specified, the default credentials are "root"/"root".

func Verbose

func Verbose() Option

Verbose enables verbose logging of MySQL connection details during setup.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL