【发布时间】:2018-01-17 16:45:52
【问题描述】:
如何正确模拟一些*sql.DB 使用接口进行单元测试的方法?例如,我想要一个 Store 结构,用作我的处理程序的数据源。它有一个conn 字段,即*sql.DB。但是在我的测试中,我想模拟数据库,所以我尝试返回的不是实际的*sql.Rows,而是*sql.Rows 应该满足的接口。代码如下:
type TestRows interface {
Scan ()
}
type TestDB interface {
Query (query string, args ...interface{}) (TestRows, error)
}
type Rows struct {
//..
}
func (r *Rows) Scan () {
fmt.Println("Scanning")
}
这是*sql.DB
type DB struct {
//...
}
func (d *DB) Query (query string, args ...inteface{}) (*Rows, error) {
return &Rows{/* .... */}, nil
}
当我想实例化 Store 时,它会抛出错误
type Store struct {
conn TestDB
}
func main() {
cl := Store {conn: &DB{}}
fmt.Println("Hello, playground")
}
cannot use DB literal (type *DB) as type TestDB in field value:
*DB does not implement TestDB (wrong type for Query method)
have Query(string) (*Rows, error)
want Query(string) (TestRows, error)
【问题讨论】:
-
不幸的是,函数签名必须完全匹配才能满足接口,并且
func(string) TestRows与func(string) *Rows不同即使*Rows满足TestRows接口。但是,有一些数据库模拟库可以解决这个问题,我的建议是使用其中之一。 -
谢谢@AlexGuerra。