【问题标题】:Extend interface throughout package在整个包中扩展接口
【发布时间】: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 等),尽管这对个人来说不是问题项目,我无法想象任何中大型应用程序会这样做。是否有另一种方法可以在一个包下拥有多个模型,可以为了测试目的而适当地模拟?

【问题讨论】:

标签: go interface


【解决方案1】:

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

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 了解更多信息。

【讨论】:

  • 我为这多么容易感到尴尬。非常感谢!
猜你喜欢
  • 2012-10-23
  • 1970-01-01
  • 2020-11-15
  • 2018-10-03
  • 1970-01-01
  • 2016-07-06
  • 1970-01-01
  • 2013-11-02
相关资源
最近更新 更多