为了学习这个,我写了一个例子,主要是一个基于 koa 的 restful 服务,然后是基于 mocha、supertest 的测试文件。
1、首先需要安装依赖
npm i supertest mocha chai --save-dev
2、npm script
[
"scripts": {
"start": "nodemon app.js",
"test": "mocha"
},
]
3、目录结构
Mocha 默认运行 test 子目录里面的测试脚本。所以,一般都会把测试脚本放在 test 目录里面,然后执行 mocha 就不需要参数了
4、编写测试文件
在我的项目中有一个关于 user 的 rest 接口,user 的数据模型大致如下:
{
"name": "wu",
"age": 24,
"likes": ["movie", "music"]
}
4.1、引入需要的模块
const request = require("supertest")("http://127.0.0.1:3000"); //初始化supertest
const DB = require("../db");
const USERS = new DB("users");
const { expect } = require("chai"); // 引入chai的expect断言
关于chai
的使用可以去官网查看,比较简单
4.2、describe
对测试进行描述,可以进行嵌套
describe('users api', () => {
describe('post: 新增一个用户', () => {
})
}
4.3、钩子
mocha
提供了四个钩子函数before、 after、afterEach 和 beforeEach
。
其中before
钩子会在本区块的所有测试用例之前执行,beforeEach
钩子会在本区快的每个测试用例之前执行,after
与afterEach
同理。
比如我想在所有测试用例开始之前清空数据库中 USERS 的数据。
describe('users api', () => {
before(async () => {
this.user = {
name: 'walala',
age: 8,
likes: []
}
await USERS.clear()
})
)
在这个钩子中我使用了async
函数,你在下边也会看到使用 done 方法通知这个异步回调完成的方式,
Mocha 内置对 Promise 的支持,允许直接返回 Promise,等到它的状态改变,再执行断言,而不用显式调用 done 方法
4.4、it
it
第一个参数是对预期结果的描述,第二个参数是一个 callback,是详细的测试行为。
describe("users api", () => {
before(async () => {
this.user = {
name: "walala",
age: 8,
likes: [],
};
await USERS.clear();
});
describe("post: 新增一个用户", () => {
it("返回200状态码,以及一个包含新增用户id的对象", (done) => {
request
.post("/user")
.send(this.user)
.expect(200)
.end((err, res) => {
if (err) done(err);
expect(res.body).to.have.property("id").equal(0);
this.id = res.body.id;
done();
});
});
});
describe("get: 获取用户", () => {
it("返回状态码200, 以及用户对象", (done) => {
request
.get(`/user/${this.id}`)
.expect(200)
.end((err, res) => {
if (err) done(err);
expect(res.body).to.be.deep.equal(this.user);
done();
});
});
});
describe("put: 修改", () => {
before((done) => {
this.user = {
name: "walala",
age: 28,
likes: [],
};
done();
});
it("返回状态码200", (done) => {
request.put(`/user/${this.id}`).send(this.user).expect(200).end(done);
});
});
describe("getAll: 获取所有用户", () => {
it("返回状态码200,以及包含用户对象的数组", (done) => {
request
.get(`/user`)
.expect(200)
.end((err, res) => {
if (err) done(err);
expect(res.body).to.be.deep.include(this.user);
done();
});
});
});
describe("delete: 删除用户", () => {
it("返回状态码200", (done) => {
request.get(`/user`).expect(200).end(done);
});
});
});
5、运行测试
npm start
npm test
测试就完成了