Skip to content

Commit

Permalink
docs(unittest): add bootstrap usage (#1278)
Browse files Browse the repository at this point in the history
  • Loading branch information
dead-horse committed Aug 2, 2017
1 parent ebbbcd5 commit 734854c
Showing 1 changed file with 41 additions and 34 deletions.
75 changes: 41 additions & 34 deletions docs/source/zh-cn/core/unittest.md
Expand Up @@ -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 function,async await 等。

### AVA
Expand Down Expand Up @@ -103,7 +103,7 @@ test
### 测试运行工具

统一使用 [egg-bin 来运行测试脚本](./development.md#单元测试)
自动将内置的 Mocha、thunk-mocha、power-assert,istanbul 等模块组合引入到测试脚本中,
自动将内置的 Mocha、co-mocha、power-assert,istanbul 等模块组合引入到测试脚本中,
让我们**聚焦精力在编写测试代码**上,而不是纠结选择那些测试周边工具和模块。

只需要在 `package.json` 上配置好 `scripts.test` 即可。
Expand Down Expand Up @@ -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 等测试。
Expand Down Expand Up @@ -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('/')
Expand All @@ -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('/')
Expand All @@ -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 测试

Expand All @@ -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 /` 请求
Expand Down Expand Up @@ -672,6 +677,8 @@ describe('some tes', () => {
});
```

**引入 `egg-mock/bootstrap` 时,会自动在 `afterEach` 钩子中还原所有的 mock,不需要在测试文件中再次编写。**

下面会详细解释一下 egg-mock 的常见使用场景。

### Mock 属性和方法
Expand Down

0 comments on commit 734854c

Please sign in to comment.