【发布时间】:2018-04-01 21:36:29
【问题描述】:
TL;DR:有没有一种方法可以扩展接口,或者是否有关于如何处理多个“数据存储”功能(一个包下的许多模型)的思想流派,同时创建一个可以正确模拟的接口控制器测试。
长篇大论: 我刚刚完成了Alex Edward's blog on organizing database access in Go 的实现,让我能够创建模拟的更好的解决方案之一是创建一个 Datastore 接口。
在模型包下我有类似于下面的代码
type Datastore interface {
AllPosts() ([]Post, error)
CreatePost(p Post) error
}
type DB struct {
*sql.DB
}
func initDB(...)( *DB) { // Code to initialize DB }
func (db *DB) AllPosts() ([]Post, error) { ... }
然后在main下:
type Env struct {
DB models.Datastore
}
func main() {
db := models.initDB(...)
env := &Env{DB: db}
httprouter.New()
r.GET("/posts", PostIndex(env))
}
func PostIndex(env *config.Env) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
w.Header().Set("Content-Type", "application/json")
posts, err := env.DB.AllPosts()
....
}
}
我一切正常,但是当我添加一个 User 模型时,我意识到我的 Datastore 接口正在大幅增长(CreatePost、CreateUser、GetAllPosts、GetAllUsers 等),尽管这对个人来说不是问题项目,我无法想象任何中大型应用程序会这样做。是否有另一种方法可以在一个包下拥有多个模型,可以为了测试目的而适当地模拟?
【问题讨论】:
-
可能值得注意的是,采用单一方法
interface的 API 可以重写为采用函数类型。见stackoverflow.com/a/63557675/12817546。