Golang 数据库 mocks(Golang database mocks)

gogeof · · 1556 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

我们[当前项目的核心](https://heupr.io/)是一个 [MemSQL](https://www.memsql.com/) 数据库,它是我们核心的数据管道;这是一个非常酷的技术,它的速度非常快,我们实在是太喜欢它了。但是,测试跟它相关的代码却有点困难,这个问题通过试验或者当遇到错误(主要是遇到错误)时,很快就可以发现。由于 Go 标准包已通过全面的测试,我只需要确保调用和依赖他们的代码在生产中也能够正常运行就好。 测试我们项目的数据库代码,我通过两个步骤完成。 通过 database/sql 包,我们有了 sql.DB 结构,它代表一系列mocks的连接,以及包含一系列与这些连接进行交互的方法。在我们的代码库中,我们使用了其中的两个(以及一个返回打开的数据库的函数): ```go func Open(driverName, dataSourceName string) (*DB, error) func (db *DB) Close() error func (db *DB) Query(query string, args ...interface{}) (*Rows, error) ``` 接着,我像下面这样创建了一个名为 sqlDB 的接口: ```go type sqlDB interface { Open(driverName, dataSourceName string) (*sql.DB, error) Close() error Query(query string, args ...interface{}) (*sql.Rows, error) } ``` 这是一个 “曲线救国” 的想法,我定义了一个由 sql.DB 结构方法实现的接口。有了这个接口,再加上单元测试可以直接使用测试对象,立马就可以测试围绕这些函数/方法的调用代码。请注意,由于在返回值中依赖了诸如 sql.Rows 之类的,导致需要一些额外的配置,但它确实让需要测试的范围更接近于实际的 database/sql 包(即,需要测试的东西更加少)。 接着,我构建第二个步骤的测试。定义了一个 dataAccess 接口,其中包含返回,将供后面处理的,准备好的对象的特定方法。这些函数将调用上面的 sqlDB 接口定义的方法,(下面的)这些方法从我们的代码库和单元测试中进一步封装了 database/sql 包: ```go type dataAccess interface { readIntegrations(query string) (map[int64]*integration, error) readSettings(query string) (map[int64]*settings, error) readEvents(query string) (map[int64][]*preprocess.Container, error) } ``` 再一次使用接口,可以让我们在测试中替换更多的生产代码,并让我们在调用这些接口代码时,可以关注(更多)不同的测试用例和场景。 简单地说: - sqlDB 接口可以让我们立即测试与数据库对象交互的相关代码(而不需要真的启动一个数据库并注入各种表) - (例如)测试处理数据库查询之类的东西 - dataAccess 接口允许我们对依赖它的值进行单元测试,例如上面返回的 map 结果 - 后面的想法也都是这样 对(依赖于)数据库相关的代码进行单元测试有不同的方法,而这就是我在 Go 项目中采用的方法 - 我非常乐意提供(我的)建议,或者方案,以及快乐地进行单元测试的方法!

via: https://dev.to/forstmeier/golang-database-mocks-1hm9

作者:John Forstmeier  译者:gogeof  校对:rxcai

本文由 GCTT 原创编译,Go语言中文网 荣誉推出


有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1556 次点击  
加入收藏 微博
被以下专栏收入,发现更多相似内容
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传