docs(unittest): add bootstrap usage (#1278)

This commit is contained in:
Yiyu He 2017-08-02 23:01:42 +08:00 committed by GitHub
parent ebbbcd574f
commit 734854c84e

View File

@ -39,7 +39,7 @@ API 升级,测试用例可以很好地检查代码是否向下兼容。
> Mocha is a feature-rich JavaScript test framework running on Node.js and in the browser, making asynchronous testing simple and fun. Mocha tests run serially, allowing for flexible and accurate reporting, while mapping uncaught exceptions to the correct test cases.
加上 [thunk-mocha](https://npmjs.com/thunk-mocha) 模块的帮助,
加上 [co-mocha](https://npmjs.com/co-mocha) 模块的帮助,
扩展了 Mocha 的多种用例书写方式,例如 generator functionasync await 等。
### AVA
@ -103,7 +103,7 @@ test
### 测试运行工具
统一使用 [egg-bin 来运行测试脚本](./development.md#单元测试)
自动将内置的 Mocha、thunk-mocha、power-assertistanbul 等模块组合引入到测试脚本中,
自动将内置的 Mocha、co-mocha、power-assertistanbul 等模块组合引入到测试脚本中,
让我们**聚焦精力在编写测试代码**上,而不是纠结选择那些测试周边工具和模块。
只需要在 `package.json` 上配置好 `scripts.test` 即可。
@ -170,6 +170,17 @@ describe('test/controller/home.test.js', () => {
这样我们就拿到了一个 app 的引用,接下来所有测试用例都会基于这个 app 进行。
更多关于创建 app 的信息请查看 [`mock.app(options)`](https://github.com/eggjs/egg-mock#options) 文档。
每一个测试文件都需要这样创建一个 app 实例非常冗余,因此 egg-mock 提供了一个 bootstrap 文件,可以直接从它上面拿到我们所常用的实例:
```js
// test/controller/home.test.js
const { app, mock, assert } = require('egg/mock/bootstrap');
describe('test/controller/home.test.js', () => {
// test cases
});
```
### ctx
我们除了 app还需要一种方式便捷地拿到 ctx方便我们进行 Extend、Service、Helper 等测试。
@ -207,9 +218,11 @@ it('should mock ctx.user', () => {
```js
// Bad
const mock = require('egg-mock');
const { app } = require('egg-mock/bootstrap');
describe('bad test', () => {
const app = mock.app();
doSomethingBefore();
it('should redirect', () => {
return app.httpRequest()
.get('/')
@ -219,20 +232,18 @@ describe('bad test', () => {
```
Mocha 刚开始运行的时候会载入所有用例,这时 describe 方法就会被调用,
`mock.app()` 就会启动。
`doSomethingBefore` 就会启动。
如果希望使用 only 的方式只执行某个用例那段代码还是会被执行,这是非预期的。
正确的做法是将其放到 before 中,只有运行这个套件中某个用例才会执行。
```js
// Good
const mock = require('egg-mock');
const { app } = require('egg-mock/bootstrap');
describe('good test', () => {
let app;
before(() => {
app = mock.app();
return app.ready();
});
before(() => doSomethingBefore());
it('should redirect', () => {
return app.httpRequest()
.get('/')
@ -257,29 +268,32 @@ describe('egg test', () => {
## 异步测试
egg-bin 会自动加载 thunk-mocha 插件测试异步调用,它支持多种写法,比如上面启动完成,`app.ready()` 返回一个 Promise。
egg-bin 会自动加载 co-mocha 插件测试异步调用,它支持多种写法,比如上面 `app.httpRequest` 方法支持返回 Promise
```js
// 使用 callback 的方式
before(done => {
const app = mm.app();
app.ready(done);
// 使用返回 Promise 的方式
it('should redirect', () => {
return app.httpRequest()
.get('/')
.expect(302);
});
// 使用 Promise
before(() => {
const app = mm.app();
return app.ready();
// 使用 callback 的方式
it('should redirect', done => {
app.httpRequest()
.get('/')
.expect(302, done);
});
// 使用 generator
before(function* () {
const app = mm.app();
yield app.ready();
it('should redirect', function* () {
yield app.httpRequest()
.get('/')
.expect(302);
});
```
使用哪种写法取决于不同应用场景,如果遇到多个异步可以使用 generator function也可以拆分成多个 before
使用哪种写法取决于不同应用场景,如果遇到多个异步可以使用 generator function也可以拆分成多个测试用例
## Controller 测试
@ -305,18 +319,9 @@ exports.index = function* (ctx) {
写一个完整的单元测试,它的测试代码 `test/controller/home.test.js` 如下:
```js
const assert = require('assert');
const mock = require('egg-mock');
const { app, mock, assert } = require('egg-mock/bootstrap');
describe('test/controller/home.test.js', () => {
let app;
before(() => {
// 创建当前应用的 app 实例
app = mock.app();
// 等待 app 启动成功,才能执行测试用例
return app.ready();
});
describe('GET /', () => {
it('should status 200 and get the body', () => {
// 对 app 发起 `GET /` 请求
@ -672,6 +677,8 @@ describe('some tes', () => {
});
```
**引入 `egg-mock/bootstrap` 时,会自动在 `afterEach` 钩子中还原所有的 mock不需要在测试文件中再次编写。**
下面会详细解释一下 egg-mock 的常见使用场景。
### Mock 属性和方法