扩展整个包

时间:2018-04-01 21:36:29

标签: go interface

TL; DR:有没有办法扩展界面,或者是否有关于如何处理多个数据存储区的思想?函数(包下的许多模型),同时创建一个可以正确模拟控制器测试的接口。

长篇故事: 我刚刚完成了Alex Edward's blog on organizing database access in 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等),尽管这不会成为问题所在。一个个人项目,我无法想象任何大中型应用程序这样做。是否有另一种方法可以在单个软件包下使用多个模型,可以针对测试目的进行适当的模拟?

1 个答案:

答案 0 :(得分:3)

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

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
}

这允许您在测试中仅模拟UserStoreSee the "Embedding" chapter in Effective Go了解更多信息。