一尘不染

测试驱动的开发,以检查涉及数据库查询的方法

go

我想使用Golang创建数据库驱动的应用程序。我正在尝试以TDD方式进行。当我尝试测试进行Sql查询的方法时,有哪些可用的软件包?

  • 我不想连接到用于开发的默认数据库。在运行测试时,我可以编写代码来占用另一个测试数据库,但是是否有已经执行该操作的go库。

  • 是否有任何可在不连接数据库的情况下进行db测试的库?

用golang进行数据库测试的标准方法是什么?


阅读 204

收藏
2020-07-02

共1个答案

一尘不染

不久前,在重构自己的一些测试时,我也遇到了类似的问题,有两种方法可以做到:

a)提供一个导出的类型和一个返回它的OpenConnect函数-例如

type DB struct {
    db *sql.DB
}

// Using http://jmoiron.github.io/sqlx/ for this example, but
// it has the same interface as database/sql
func Open(opts *Options) (*DB, error) {
    db, err := sqlx.Connect(opts.Driver, fmt.Sprintf("host=%s user=%s dbname=%s sslmode=%s", opts.Host, opts.User, opts.Name, opts.SSL))
    if err != nil {
        return nil, err
    }

    return &DB{db}, nil
}

…然后进行 每个 测试,编写设置和拆卸函数,这些函数返回*DB您定义数据库功能的实例(作为方法-即func (db *DB) GetUser(user *User) (bool, error)):

// Setup the test environment.
func setup() (*DB, error) {
    err := withTestDB()
    if err != nil {
        return nil, err
    }

    // testOptions is a global in this case, but you could easily
    // create one per-test
    db, err := Open(testOptions)
    if err != nil {
        return nil, err
    }

    // Loads our test schema
    db.MustLoad()
    return db, nil
}

// Create our test database.
func withTestDB() error {
    db, err := open()
    if err != nil {
        return err
    }
    defer db.Close()

    _, err = db.Exec(fmt.Sprintf("CREATE DATABASE %s;", testOptions.Name))
    if err != nil {
        return err
    }

    return nil
}

请注意,这有点“集成”测试,但是我强烈希望针对“真实”数据库进行测试,因为模拟接口不会帮助您捕获查询/查询语法的问题。

b)尽管在应用程序方面扩展性较差,但替代方法是在测试中db *sql.DB初始化一个全局变量,init()因为测试没有确定的顺序init(),因此您可以在其中运行该测试。即

var db *sql.DB

func init() {
    var err error
    // Note the = and *not* the assignment - we don't want to shadow our global
    db, err = sqlx.Connect(...)
    if err != nil {
        ...
    }

    err := db.loadTestSchema
    // etc.
}

func TestGetUser(t *testing.T) {
   user := User{}
   exists, err := db.GetUser(user)
   ...
}

您可以在drone.io的GitHub
repo中
找到一些实际示例,并且我还建议您阅读有关构建Go应用程序(尤其是DB东西)的文章。

2020-07-02