被测试的代码中有一个方法,该方法只是尝试获取数据库连接,否则将返回错误。
它以及涉及的结构定义如下:
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
(“无连接”),并且非零(“健全性测试”)
答案 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))
}
})