我正在使用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")
    }
}

推荐答案

pool.Retry的默认最长等待时间为one minute.只是猜测,也许您的postgres数据库容器不会在一分钟内出现.

try 增加MaxWait时间,例如pool.MaxWait = 20 * time.Minute

Go相关问答推荐

使用Gorm创建自定义连接表

golang 的通用 map 功能

如何在使用中介资源时处理函数中的`defer`

如何给杜松子wine 的路由加上一个名字,比如Laravel ?

文件路径.Abs()未在结果中提供子目录

如何在 Chi Router 的受保护路由下提供静态文件(尤其是图像)?

在运行时更改 Go lang slog 的日志(log)级别

Go 中将 int 切片转换为自定义 int 切片指针类型的函数

调用库和直接操作效率有区别吗?

Json.Unmarshal() 和 gin.BindJson() 之间的区别

如何将已知类型转换为指向switch 中类型参数的指针?

Github Actions Go lambda 项目不同的 sha256sums

Go 中的 YAML 自定义标签

Gremlin-Go:树步骤不可序列化

Apache Beam 左加入 Go

如何使用 Go 代理状态为 OK 的预检请求?

将 []float64 像素切片转换为图像

如何正确为 Go 中的值设置多种类型?

Go generics:我会在哪里使用 any 而不是 interface{}?

Golang 将类型 [N]byte 转换为 []byte