1 回答

TA貢獻1752條經驗 獲得超4個贊
不確定這是最好的方法,但我已經連接了幾個示例,并在測試設置上通過 [golang-migrate] lib 提出了完整遷移。
下面TestMain是設置 Dockertest 與 postgres 數據庫連接的設置函數。就在m.Run()運行測試之前,有runMigrations一個使用 golang-migrate 將所有腳本拉到本地目錄并將它們應用到數據庫。它有效,但速度很慢。
func TestMain(m *testing.M) {
// uses a sensible default on windows (tcp/http) and linux/osx (socket)
pool, err := dockertest.NewPool("")
if err != nil {
log.Fatalf("Could not connect to docker: %s", err)
}
// pulls an image, creates a container based on it and runs it
resource, err := pool.RunWithOptions(&dockertest.RunOptions{
Repository: "postgres",
Tag: "11",
Env: []string{
"POSTGRES_PASSWORD=secret",
"POSTGRES_USER=user_name",
"POSTGRES_DB=dbname",
"listen_addresses = '*'",
},
}, func(config *docker.HostConfig) {
// set AutoRemove to true so that stopped container goes away by itself
config.AutoRemove = true
config.RestartPolicy = docker.RestartPolicy{Name: "no"}
})
if err != nil {
log.Fatalf("Could not start resource: %s", err)
}
hostAndPort := resource.GetHostPort("5432/tcp")
databaseUrl := fmt.Sprintf("postgres://user_name:secret@%s/dbname?sslmode=disable", hostAndPort)
log.Println("Connecting to database on url: ", databaseUrl)
resource.Expire(120) // Tell docker to hard kill the container in 120 seconds
// exponential backoff-retry, because the application in the container might not be ready to accept connections yet
pool.MaxWait = 120 * time.Second
if err = pool.Retry(func() error {
db, err = sql.Open("postgres", databaseUrl)
if err != nil {
return err
}
return db.Ping()
}); err != nil {
log.Fatalf("Could not connect to docker: %s", err)
}
// Migrating DB
if err := runMigrations("../migrations", db); err != nil {
log.Fatalf("Could not migrate db: %s", err)
}
//Run tests
code := m.Run()
// You can't defer this because os.Exit doesn't care for defer
if err := pool.Purge(resource); err != nil {
log.Fatalf("Could not purge resource: %s", err)
}
os.Exit(code)
}
func runMigrations(migrationsPath string, db *sql.DB) error {
if migrationsPath == "" {
return errors.New("missing migrations path")
}
driver, err := postgres.WithInstance(db, &postgres.Config{})
if err != nil {
return err
}
m, err := migrate.NewWithDatabaseInstance("file://"+migrationsPath, "postgres", driver)
if err != nil {
return err
}
err = m.Up()
if err != nil && err != migrate.ErrNoChange {
return err
}
return nil
}
- 1 回答
- 0 關注
- 153 瀏覽
添加回答
舉報