在整个软件包中扩展接口



tl; dr; dr:是否有一种扩展接口的方法,或者在创建多个"数据存储"功能(软件包下的许多模型(时是否有思想流派可以正确模拟控制器测试的接口。

长篇小说:我刚刚完成了Alex Edward在GO中组织数据库访问的博客的实施,这是让我创建模拟的更好解决方案之一涉及创建数据存储界面。

在模型软件包下,我的代码类似于以下

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()
    ....
  }
}

我的所有功能都可以,但是当我添加用户模型时,我意识到我的数据存储界面正在巨大增长(createpost,createuser,getallPosts,getallusers等(,尽管这对个人来说不是问题项目,我无法想象这样做的任何中等大规模应用程序。是否有另一种方法可以在单个软件包下进行多个模型,可以正确模拟用于测试目的?

您可以使用一组较小的接口,如果需要,仍然将它们组合成一个。

type UserStore interface {
  AllUsers() ([]User, error)
  CreateUser(u User) error
}
type PostStore interface {
  AllPosts() ([]Post, error)
  CreatePost(p Post) error
}
type DataStore interface {
  UserStore
  PostStore
}

这使您可以在测试中模拟UserStore。有关更多信息,请参见有效的"嵌入"一章。

最新更新