新人在学习egg.js 中,一些关单元测试的疑惑,请前辈们指导一下。
发布于 24 天前 作者 hopperhuang 1576 次浏览 来自 问答

我的疑惑是,涉及单元测试在涉及数据库的部分应该怎么处理? 最近在学习node.js 和 egg框架。看到了关于单元测试的部分。就是对单元测试的时候,涉及网络io 和数据库的部分逻辑我们应该怎么处理呢?

我看到的文章的大概方案有两种。 第一种是: 通过单元测试框架的相关钩子,在启动测试前,连接到相应的测试数据库(测试数据库预先写入好需要的数据)中,然后再进行相应的测试。

第二种方法是: 关于数据库和网络io的,都使用mock方法。将数据库和网络io的相应测试分离。

我是认同第二种方法的。因为涉及到外部的东西,就应该放到集成测试中去,这并不是单元测试的目标。所以,应该用mock方法去模拟相应的操作。 但是,我又没找到可以mock数据库操作的库。google过了,好像也没找到相应的方法。

不知道前辈们在单元测试时,是如果测试这部分(涉及数据库和网络io)的逻辑的。请给后辈一些指点,谢谢各位了!!

11 回复

从来没写过单元测试,我们团队也是,都是直接在开发环境跑一下,没啥问题直接发测试环境,让测试测,有bug再改。至今没有理解单元测试的意义。

2个方案并没有冲突,涉及到DB你可以使用方案1,在setup中建立测试库,填充必要数据,在teardown中拆除测试库。每次运行用例都应该保证测试库是全新的。 涉及三方服务的,你可以以mock为主

  1. 数据库,如果数据库是私有的自己开发的,那你没办法单独测试,如果是市面上能安装的,那你单元测试环境装一个并不是难的事情,不管是shell环境还是docker,都可以很顺滑的完成,另外数据库mock数据是要单元测试统一准备的,运行的时候插入数据库,你所需要的就是提供一个可访问的数据库dsn。
  2. 网络io,建议用eggjs写的话网络请求就用自带的,因为自带的egg会有钩子,这个请求可以mock,这样你就可以测试更底层的代码逻辑。 单元测试在一个复杂逻辑的系统下我觉得的确很难去做,不管是分层还是对各种类型的io,但是如果一个系统分层做得不错,又比如微服务模式的开发,单元测试是不错的提升效率的办法,因为以联调起来,debug非常难受,如果单个服务或者某个层面的服务已经对一些关键的接口进行了边缘条件的测试,那么一般错误都会只是服务和服务间的约定,而出现逻辑性概率就低了很多。

@wuyugege 你这有点猛啊,重构的时候怎么办,改动一点的时候,怎么保证其他的都是OK的,测试在全测一遍吗

@dengnan123 重构是不可能重构的。有改动的话,全回归,人工测。这应该是小团队的现状吧,外包没见过写单元测试的,虽然我们不是外包,但只有几个人。

弄一个完整的测试环境呗,数据库、Redis等资源来一套。每次测试的时候都清空。测试的数据尽量落地到数据库,越接近真实越可靠。 依赖其他服务,使用 Test Double,https://sinonjs.org

在我的实际运用中,只有一个方案:

  • 不会 Mock 部分:本服务的数据库及缓存不会 Mock,这部分如果 Mock 了整个测试就是一个空壳子。比如我测试一个注册用户的场景,直接 Mock 注册用户的结果是 useId: 1,然后断言 userId = 1。这种测试用例不明白它的用处是什么,流程没有完全覆盖,如果就是 插入数据表这个操作有问题呢?
  • Mock 部分:一般来说,调用其它服务(比如你跟另外一个项目组合作,他们用的 C++,可能他们服务都没有开发完,或者你本地部署不了)、第三方服务的部分会 Mock。

没有会搞单元测试的人带,新人搞的话,覆盖率和测试用例都是一个问题 我们之前也搞,但是现在业务压力上来了,感觉搞不动了 写功能的时间都不够了,写测试的精力相对就少了很多

不写用例,这个项目只会越做越痛苦。然后就会出现各种 bug,有些是新写的,有些是改动导致的。最后没人敢接盘。 大型项目只所以稳定就是有比较完备测试用例,保证有问题代码第一时间发现并改掉。说单元测试没用的,可能并不关注代码质量和项目的稳定性。

@hopperhuang 数据库的测试,你可以在 ci 机器上起测试数据库。推荐使用 sequelize 这类 orm 吧,已经把 mock 什么的方法都做好了~

@okoala 确实,看到orm 的文档了,可以用egg-sequelize 来跑单元测试。

首先还是推荐用 fake date 测一下数据库 sql 部分的, 如果你想 mock, 可以重写 mode 里的方法

image.png

回到顶部