英文:
Basic setup of Golang SQL unit testing with dockertest
问题
我正在使用dockertest进行SQL单元测试。这只是一个简单的连接到*sqlx.DB
,但不知何故在连接到数据库时生成了一个错误Error: EOF
。我无法确定错误,并且可能配置错误。
import (
"fmt"
"log"
"os"
"testing"
_ "github.com/lib/pq"
"github.com/jmoiron/sqlx"
"github.com/ory/dockertest/v3"
"github.com/ory/dockertest/v3/docker"
)
var (
host = "localhost"
user = "postgres"
password = "postgres"
dbName = "db_test"
port = "5437"
dsn = "host=%s port=%s user=%s password=%s dbname=%s sslmode=disable timezone=UTC connect_timeout=30"
)
var resource *dockertest.Resource
var pool *dockertest.Pool
var testDB *sqlx.DB
var testRepo Repo
func TestMain(m *testing.M) {
// connect to docker; fail if docker not running
p, err := dockertest.NewPool("")
if err != nil {
log.Fatalf("could not connect to docker; is it running? %s", err)
}
pool = p
opts := dockertest.RunOptions{
Repository: "postgres",
Tag: "14.5", // same as docker compose
Env: []string{
"POSTGRES_USER=" + user,
"POSTGRES_PASSWORD=" + password,
"POSTGRES_DB=" + dbName,
},
ExposedPorts: []string{"5432"},
PortBindings: map[docker.Port][]docker.PortBinding{
"5432": {
{HostIP: "0.0.0.0", HostPort: port},
},
},
}
resource, err = pool.RunWithOptions(&opts)
if err != nil {
// _ = pool.Purge(resource)
log.Fatalf("could not start resource: %s", err)
}
if err := pool.Retry(func() error {
var err error
testDB, err = sqlx.Connect("postgres", fmt.Sprintf(dsn, host, port, user, password, dbName))
if err != nil {
log.Println("Error:", err)
return err
}
return testDB.Ping()
}); err != nil {
_ = pool.Purge(resource)
log.Fatalf("could not connect to database: %s", err)
}
err = createTables()
if err != nil {
log.Fatalf("error creating tables: %s", err)
}
code := m.Run()
if err := pool.Purge(resource); err != nil {
log.Fatalf("could not purge resource: %s", err)
}
testRepo = &repo{db: testDB}
os.Exit(code)
}
func createTables() error {
tableSQL, err := os.ReadFile("./testdata/tables.sql")
if err != nil {
fmt.Println(err)
return err
}
_, err = testDB.Exec(string(tableSQL))
if err != nil {
fmt.Println(err)
return err
}
return nil
}
func Test_pingDB(t *testing.T) {
err := testDB.Ping()
if err != nil {
t.Error("can't ping database")
}
}
英文:
I am performing SQL Unit Testing using dockertest. This is just a simple connection to *sqlx.DB
but somehow it is generating an error Error: EOF
when connecting to the database. I am unable to identify the error and I may have configured it wrongly.
import (
"fmt"
"log"
"os"
"testing"
_ "github.com/lib/pq"
"github.com/jmoiron/sqlx"
"github.com/ory/dockertest/v3"
"github.com/ory/dockertest/v3/docker"
)
var (
host = "localhost"
user = "postgres"
password = "postgres"
dbName = "db_test"
port = "5437"
dsn = "host=%s port=%s user=%s password=%s dbname=%s sslmode=disable timezone=UTC connect_timeout=30"
)
var resource *dockertest.Resource
var pool *dockertest.Pool
var testDB *sqlx.DB
var testRepo Repo
func TestMain(m *testing.M) {
// connect to docker; fail if docker not running
p, err := dockertest.NewPool("")
if err != nil {
log.Fatalf("could not connect to docker; is it running? %s", err)
}
pool = p
opts := dockertest.RunOptions{
Repository: "postgres",
Tag: "14.5", // same as docker compose
Env: []string{
"POSTGRES_USER=" + user,
"POSTGRES_PASSWORD=" + password,
"POSTGRES_DB=" + dbName,
},
ExposedPorts: []string{"5432"},
PortBindings: map[docker.Port][]docker.PortBinding{
"5432": {
{HostIP: "0.0.0.0", HostPort: port},
},
},
}
resource, err = pool.RunWithOptions(&opts)
if err != nil {
// _ = pool.Purge(resource)
log.Fatalf("could not start resource: %s", err)
}
if err := pool.Retry(func() error {
var err error
testDB, err = sqlx.Connect("postgres", fmt.Sprintf(dsn, host, port, user, password, dbName))
if err != nil {
log.Println("Error:", err)
return err
}
return testDB.Ping()
}); err != nil {
_ = pool.Purge(resource)
log.Fatalf("could not connect to database: %s", err)
}
err = createTables()
if err != nil {
log.Fatalf("error creating tables: %s", err)
}
code := m.Run()
if err := pool.Purge(resource); err != nil {
log.Fatalf("could not purge resource: %s", err)
}
testRepo = &repo{db: testDB}
os.Exit(code)
}
func createTables() error {
tableSQL, err := os.ReadFile("./testdata/tables.sql")
if err != nil {
fmt.Println(err)
return err
}
_, err = testDB.Exec(string(tableSQL))
if err != nil {
fmt.Println(err)
return err
}
return nil
}
func Test_pingDB(t *testing.T) {
err := testDB.Ping()
if err != nil {
t.Error("can't ping database")
}
}
答案1
得分: 1
pool.Retry
的默认最大等待时间是一分钟。只是猜测,也许你的Postgres数据库容器在一分钟内没有启动起来。
尝试使用如下代码增加MaxWait
的时间:pool.MaxWait = 20 * time.Minute
英文:
Default max wait time for pool.Retry
is one minute. Just guessing, maybe your postgres db container is not coming up in one minute.
Try increasing the MaxWait time with e.g. pool.MaxWait = 20 * time.Minute
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论