Skip to content

Instantly share code, notes, and snippets.

@up1
Last active January 29, 2025 15:34
Show Gist options
  • Save up1/ceaff31729dacf305bd75d78b4916c36 to your computer and use it in GitHub Desktop.
Save up1/ceaff31729dacf305bd75d78b4916c36 to your computer and use it in GitHub Desktop.
Go Testing + MySQL + TestContainer
$go test ./... -cover -v
=== RUN TestSuccessWithGetDataByID
2025/01/29 22:24:37 github.com/testcontainers/testcontainers-go - Connected to docker:
Server Version: 27.4.0
API Version: 1.46
Operating System: Docker Desktop
Total Memory: 11948 MB
Testcontainers for Go Version: v0.35.0
Resolved Docker Host: unix:///var/run/docker.sock
Resolved Docker Socket Path: /var/run/docker.sock
Test SessionID: 8e25c4b653a5628ce04b68596f77da89abc103ef9691667f86ed825f1cdba63b
Test ProcessID: b6c35f7a-21d5-4958-9c80-0325646acd02
2025/01/29 22:24:41 🐳 Creating container for image mysql:8.0.36
2025/01/29 22:24:41 🐳 Creating container for image testcontainers/ryuk:0.11.0
2025/01/29 22:24:41 βœ… Container created: bfcf34699fad
2025/01/29 22:24:41 🐳 Starting container: bfcf34699fad
2025/01/29 22:24:42 βœ… Container started: bfcf34699fad
2025/01/29 22:24:42 ⏳ Waiting for container id bfcf34699fad image: testcontainers/ryuk:0.11.0. Waiting for: &{Port:8080/tcp timeout:<nil> PollInterval:100ms skipInternalCheck:false}
2025/01/29 22:24:42 πŸ”” Container is ready: bfcf34699fad
2025/01/29 22:24:42 βœ… Container created: a5052fbf4db2
2025/01/29 22:24:42 🐳 Starting container: a5052fbf4db2
2025/01/29 22:24:42 βœ… Container started: a5052fbf4db2
2025/01/29 22:24:42 ⏳ Waiting for container id a5052fbf4db2 image: mysql:8.0.36. Waiting for: &{timeout:<nil> Log:port: 3306 MySQL Community Server IsRegexp:false Occurrence:1 PollInterval:100ms check:<nil> submatchCallback:<nil> re:<nil> log:[]}
2025/01/29 22:24:48 πŸ”” Container is ready: a5052fbf4db2
--- PASS: TestSuccessWithGetDataByID (10.46s)
PASS
coverage: 75.0% of statements
ok demo/db 10.980s coverage: 75.0% of statements
package db
import "database/sql"
type User struct {
ID int
Name string
}
type DB struct {
db *sql.DB
}
func NewDB(db *sql.DB) *DB {
return &DB{db: db}
}
func (d *DB) FindById(id int) (*User, error) {
var user User
err := d.db.QueryRow("SELECT id, name FROM users WHERE id = ?", id).Scan(&user.ID, &user.Name)
if err == sql.ErrNoRows {
return nil, nil
}
if err != nil {
return nil, err
}
return &user, nil
}
package db_test
import (
"context"
"database/sql"
"demo/db"
"path/filepath"
"testing"
_ "github.com/go-sql-driver/mysql"
"github.com/stretchr/testify/assert"
"github.com/testcontainers/testcontainers-go/modules/mysql"
)
func TestDB(t *testing.T) {
// Setup test container once for all tests
ctx := context.Background()
mysqlContainer, err := mysql.Run(ctx,
"mysql:8.0.36",
mysql.WithDatabase("demo-data"),
mysql.WithUsername("user01"),
mysql.WithPassword("pass01"),
mysql.WithScripts(filepath.Join("testdata", "schema.sql")),
)
if err != nil {
assert.Fail(t, "failed to start container")
}
connStr, err := mysqlContainer.ConnectionString(ctx)
if err != nil {
assert.Fail(t, "failed to get connection string")
}
_db, err := sql.Open("mysql", connStr)
if err != nil {
assert.Fail(t, "failed to open db connection")
}
defer _db.Close()
testDB := db.NewDB(_db)
t.Run("Success get user by ID", func(t *testing.T) {
user, err := testDB.FindById(1)
assert.Nil(t, err)
assert.Equal(t, 1, user.ID)
assert.Equal(t, "Somkiat", user.Name)
})
t.Run("Not found user by ID", func(t *testing.T) {
user, err := testDB.FindById(999)
assert.Nil(t, err)
assert.Nil(t, user)
})
}
package db_test
import (
"context"
"database/sql"
"demo/db"
"path/filepath"
"testing"
_ "github.com/go-sql-driver/mysql"
"github.com/stretchr/testify/assert"
"github.com/testcontainers/testcontainers-go/modules/mysql"
)
// Testing with testcontainers + mysql
func TestSuccessWithGetDataByID(t *testing.T) {
// Start a new container of MySQL Database
ctx := context.Background()
mysqlContainer, err := mysql.Run(ctx,
"mysql:8.0.36",
mysql.WithDatabase("demo-data"),
mysql.WithUsername("user01"),
mysql.WithPassword("pass01"),
mysql.WithScripts(filepath.Join("testdata", "schema.sql")),
)
if err != nil {
assert.Fail(t, "failed to start container")
}
connStr, err := mysqlContainer.ConnectionString(ctx)
if err != nil {
assert.Fail(t, "failed to get connection string")
}
// Act
_db, err := sql.Open("mysql", connStr)
testDB := db.NewDB(_db)
user, err := testDB.FindById(1)
// Assert
assert.Nil(t, err)
assert.Equal(t, 1, user.ID)
assert.Equal(t, "Somkiat", user.Name)
}
CREATE TABLE IF NOT EXISTS users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL
);
INSERT INTO users (name) VALUES ('Somkiat');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment