golang:为现有类型构建接口以使代码可测试

时间:2016-12-14 23:33:18

标签: go

我构建了以下2个接口,以便创建我的代码,这使得对 sql 包的调用成为可测试的:

type Database interface {
    Close() error
    Query(string, ...interface{}) (DatabaseRows, error)
}

type DatabaseRows interface {
    Close() error
    Next() bool
    Scan(...interface{}) error
}

我要测试的实际代码是:

func getDatabase(connectionString string) (db Database, err error) {
    if db , err = sql.Open("mysql", connectionString); err != nil {
        glog.V(0).Infof("Error %s", err)
    }
    return
}

但这无法编译:

  

* sql.DB没有实现Database(Query方法的类型错误)

     

有Query(string,... interface {})(* sql.Rows,error)

     

想要Query(string,... interface {})(DatabaseRows,error)

如果我理解正确,它告诉我它无法返回 * Row ,其中 DatabaseRow 是预期的,即使 Rows struct in正在实现我在 DatabaseRows 接口中声明的所有3个函数。

为什么编译器不进行该关联?

1 个答案:

答案 0 :(得分:0)

如果您还没有找到解决此问题的方法,我建议您围绕数据库调用创建一个新的API,该API实际上会返回您想要的内容。这意味着您需要做出一些判断,但是对问题进行一点思考之后,您的测试最终将变得更加干净。

例如,如果您的数据库包含这样的表

+------------+----------+-----+-------------------+
| EmployeeID | Name     | Age | Salary            |
+------------+----------+-----+-------------------+
| 123        | Kara Bob | 28  | 1 Million Dollars |
+ ...

创建这样的界面

type Employee interface {
    GetEmployeeId() int
    GetName() string
    ...
}

然后创建一个实际版本,该版本调用您的SQL数据库,然后创建一个带有struct字段供您测试的假版本。