我按照本教程模拟数据库连接。但是当我尝试更进一步并为 Query 方法的返回类型实现一个接口时,我得到一个错误。这是不适用于MockDB但适用于的工作版本main:// The DB interfacetype SQLDB interface { Query(query string, args ...interface{}) (*sql.Rows, error)}type MockDB struct { // ...}func (m *MockDB) Query(query string, args ...interface{}) (SQLRows, error) { // var row MockRows // ... return rows, nil}// #################################// The Rows interfacetype SQLRows interface { Next() bool Scan(dest ...interface{}) error}type MockRows struct { // ...}func (m *MockRows) Next() bool { // ... return true}func (m *MockRows) Scan(dest ...interface{}) error { // ... return nil}// #################################// Usagefunc GetStuff(db SQLDB) (*sql.Rows, error) { results := db.Query("query") // ... return results, nil}// #################################// Mainvar db SQLDBfunc main() { db = sql.Open("driver", "uri") results := GetResult(db)}// #################################// Testfunc TestGetStuff(t *testing.T) { mockDB = new(MockDB) results := GetResult(mockDB) // ...}这适用于 main,但不适用于测试,并且在运行测试时出现以下错误:*MockDB does not implement SQLDB (wrong type for Query method) have Query(string, ...interface {}) (SQLRows, error) want Query(string, ...interface {}) (*sql.Rows, error)这是适用于MockDB但不适用的版本main:// The DB interfacetype SQLDB interface { Query(query string, args ...interface{}) (SQLRows, error)}type MockDB struct { // ...}func (m *MockDB) Query(query string, args ...interface{}) (SQLRows, error) { // <<<<<< Changed // var row MockRows // ... return rows, nil}// #################################// The Rows interfacetype SQLRows interface { Next() bool Scan(dest ...interface{}) error}type MockRows struct { // ...}这是错误: *sql.DB does not implement SQLDB (wrong type for Query method) have Query(string, ...interface {}) (*sql.Rows, error) want Query(string, ...interface {}) (SQLRows, error)我怎样才能使它适用于两者?还是根本做不到?
1 回答
慕虎7371278
TA贡献1802条经验 获得超4个赞
您可以做的是包装*sql.DB在一个瘦包装器中,该包装器实现SQLDB并且其实现只是将调用委托给 wrapped *sql.DB。
type dbwrapper struct{ db *sql.DB }
func (w *dbwrapper) Query(query string, args ...interface{}) (SQLRows, error) {
return w.db.Query(query, args...) // delegate
}
现在不是*sql.DB直接使用,而是将其包装在dbwrapper其中,然后可以用作SQLDB接口。
func GetStuff(db SQLDB) (SQLRows, error) {
// ...
}
func main() {
db, err := sql.Open("driver", "uri")
if err != nil {
panic(err)
}
w := &dbwrapper{db}
rows, err := GetStuff(w) // will compile
// ...
}
- 1 回答
- 0 关注
- 192 浏览
添加回答
举报
0/150
提交
取消