卓越飞翔博客卓越飞翔博客

卓越飞翔 - 您值得收藏的技术分享站
技术文章34200本站已运行391

使用 dockertest 进行 Golang SQL 单元测试的基本设置

使用 dockertest 进行 golang sql 单元测试的基本设置

问题内容

我正在使用 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 的默认最长等待时间为 一分钟一个>。只是猜测,也许您的 postgres 数据库容器不会在一分钟内启动。

尝试增加 MaxWait 时间,例如pool.MaxWait = 20 * 时间.Minute

卓越飞翔博客
上一篇: 为什么当我将文件 %GOROOT%\tour.exe 移动到 foo\tour.exe 时,Gotour 无法运行?
下一篇: 返回列表
留言与评论(共有 0 条评论)
   
验证码:
隐藏边栏