数据库连接的单元测试策略融入Golang

时间:2018-08-13 17:07:49

标签: unit-testing go

被测试的代码中有一个方法,该方法只是尝试获取数据库连接,否则将返回错误。

它以及涉及的结构定义如下:

type DatabaseContext struct {
    Context
    Database DatabaseSt
}


// //GetInfo Returns the context.
// func (c *DatabaseContext) GetInfo() *Context {
//  return &c.Context
// }

//GetDB Gets the database connection from the connection string.
func (c *DatabaseContext) GetDB() (*sql.DB, *errors.ErrorSt) {
    var errSt *errors.ErrorSt
    if c.Database.dbConnection == nil {
        c.Database.dbConnection, errSt = c.openDB()
        if errSt != nil {
            return nil, errSt
        }
        c.Database.dbConnection.SetMaxOpenConns(50)
    }
    return c.Database.dbConnection, nil
}

在同一文件中可能击中的其他方法如下:

//openDB opens the database with the connection string.
func (c *DatabaseContext) openDB() (*sql.DB, *errors.ErrorSt) {
    if c.Database.DBConnectionStr == "" {
        c.GetDatabase()
    }
    return db.OpenConnection(c.Database.DBConnectionStr, c.Database.InterpolateParams)

}

//CloseDB Closes the database.
func (c *DatabaseContext) CloseDB() {
    if c.Database.dbConnection != nil {
        c.Database.dbConnection.Close()
    }
}

//SetDatabaseString Sets the database string into the session.
func (c *DatabaseContext) SetDatabaseString(str string) {
    c.Database.DBConnectionStr = str
    i := strings.Index(str, ")/") + 2
    c.Database.DBName = str[i:]
    c.SetDatabase()
}

//GetDatabaseString Gets the database string from the session.
func (c *DatabaseContext) GetDatabase() {
    if dbIntf := c.GetFromSession("Database"); dbIntf != nil {
        c.Database = dbIntf.(DatabaseSt)
    }
}

//SetDatabaseString Sets the database string into the session.
func (c *DatabaseContext) SetDatabase() {
    c.SetToSession("Database", c.Database)
}

幸运的是,DatabaseContext实现了DatabaseContextIntf,我想将其用于测试。我的本能是直截了当地模拟DatabaseContext,但是那不是一个接口,所以不起作用(在Golang中,您只能模拟接口)。

我该如何进行测试,而又不破坏真正的数据库,因为它可能会导致我无法控制的失败(因此在测试中创建错误的失败)?

更新,我的问题与可疑重复项有所不同,因为他们的问题与数据库条目有关,而不是与连接有关。标记的重复项将this library用作答案,但是,为了进行测试,其中没有方法返回无效的“连接”。最好的方法是New,它创建一个测试双重连接,并且无法控制返回值的状态(我需要在一个测试中将其设为nil(“无连接”),并且非零(“健全性测试”)

1 个答案:

答案 0 :(得分:0)

我最终使测试包与被测代码的包相同(这允许Visual Studio Code中的测试生成器将生成的测试正确放置在测试文件中,并且不会引起混淆,以及给我访问我曾经使用过的未导出字段的权限),然后我就冒充了DatabaseContext

我的测试用例如下:

t.Run("SanityTest", func(t *testing.T) {
    c := new(DatabaseContext)
    assert.Nil(t, c.Database.dbConnection)
    database, err := c.GetDB()
    defer database.Close()
    assert.NotNil(t, database)
    if !assert.Nil(t, err) {
        t.Error(err.ToString(false))
    }
})