mocha诞生于2011年,是一个特征丰富的javascript测试框架,能够运行在node.js和浏览器上,使异步测试更简单和有趣。mocha测试连续运行,容许灵活和准确的报告,同时将未捕获的异常映射到正确的测试用例。javascript
公司项目中,没有自动化的单元测试,而是经过写if/else判断,多少有点懵逼html
所在在种种考虑之下,咱们就选择mocha测试框架作单元测试前端
在terminal里运行vue
npm run mochawesome
复制代码
完成项目中的单元测试java
单击 file:///
+项目所在地址+/mochawesome-report/mochawesome.html
node
最终获得的就是这一份测试报告react
须要测试的代码以下git
'use strict';
const router = require('express').Router();
const passport = require('passport');
const User = require('../collections/user');
const log = require('../services/logger').createLogger('userAuthentication');
const AUTH_ERR = require('../constant/errMessage').AUTH;
const COMM_ERR = require('../constant/errMessage').COMMON;
/** * @api {get} /v1/auth/ User auth information * @apiName UserAuthInfo * @apiGroup userAuthentication * * @apiParam {null} null. * * @apiSuccess {String} username The username of the current user. * @apiSuccess {date} last User last logon time. * * @apiSuccessExample Success-Response: * HTTP/1.1 200 OK * { * "username": "test", * "last": "2019-06-03T06:22:53.567Z" * } * * @apiError NOT_LOGIN The current User was not logon. * * @apiErrorExample Error-Response: * HTTP/1.1 401 Unauthorized * { * "err": "NOT_LOGIN", * "message": "User has not logon in!" * } */
router.get('/', function(req, res) {
if (req.user) {
res.json({
username: req.user.username,
last: req.user.last
});
} else {
res.status(401).json({
err: 'NOT_LOGIN',
message: AUTH_ERR.NOT_LOGIN
});
}
});
/** * @api {post} /v1/auth/register User Register * @apiName UserRegister * @apiGroup userAuthentication * * @apiParam {String} username New user's name. * @apiParam {String} password New user's password. * * @apiSuccess {String} username The username of the register user. * @apiSuccess {string} message The registering success info. * * @apiSuccessExample Success-Response: * HTTP/1.1 200 OK * { * "username": "gushen", * "message": "User registered successful" * } * * @apiError REGISTER_FAILURE The register failure. * * @apiErrorExample Error-Response: * HTTP/1.1 500 Internal Server Error * { * "err": "REGISTER_FAILURE", * "message": "User register failure!" * } */
router.post('/register', function(req, res, next) {
User.register(new User({ username: req.body.username }), req.body.password, function(err) {
if (err) {
log.error(err);
res.status(500).json({
err: 'REGISTER_FAILURE',
message: AUTH_ERR.REGISTER_FAILURE
});
return;
}
log.info('user ' + req.body.username + ' registered successful!');
res.json({
username: req.body.username,
message: 'User registered successful'
});
});
});
/** * @api {post} /v1/auth/login User login * @apiName UserLogin * @apiGroup userAuthentication * * @apiParam {String} username User's name. * @apiParam {String} password User's password. * * @apiSuccess {String} username The username of the register user. * @apiSuccess {string} message The messgaer if the user login in successful. * * @apiSuccessExample Success-Response: * HTTP/1.1 200 OK * { * "username": "test", * "message": "Authentication Success" * } * * @apiError REGISTER_FAILURE The register failure. * * @apiErrorExample Error-Response: * HTTP/1.1 401 Unauthorized * { * "err": "AUTHENTICATE_FAILURE", * "message": "Authenticate failure" * } */
router.post('/login', isAhenticated, passport.authenticate('local'), function(req, res) {
if (req.user) {
log.info(`${req.user.username} login in successful`);
res.json({
username: req.user.username,
message: 'Authentication Success'
});
return;
}
log.info(`${req.user.username} login failure`);
res.status(401).json({
err: 'AUTHENTICATE_FAILURE',
message: `${req.user.username} login failure`
});
});
/** * @api {post} /v1/auth/user/:username User delete * @apiName UserDelete * @apiGroup userAuthentication * * @apiParam {String} username User's name. * * @apiSuccess {String} username The username of the deleted user. * @apiSuccess {string} message The message if deleting successful. * * @apiSuccessExample Success-Response: * HTTP/1.1 200 OK * { * "username": "gushen", * "message": "Delete User Successful" * } * * @apiError NOT_LOGIN The register failure. * * @apiErrorExample Error-Response: * HTTP/1.1 401 Unauthorized * { * "err": "NOT_LOGIN", * "message": "User has not logon in!" * } */
router.delete('/user/:username', function(req, res) {
if (!req.user) {
res.status(401).json({
err: 'NOT_LOGIN',
message: AUTH_ERR.NOT_LOGIN
});
return;
}
// if (!req.params.username) {
// res.json({
// err: 'PARAMS_NOT_CORRECT',
// message: 'No deleted user name'
// });
// return;
// }
User.deleteOne({ username: req.params.username }, (err) => {
if (err) {
log.error(err);
res.status(500).json({
err: 'SERVER_ERROR',
message: COMM_ERR.SERVER_ERROR
});
return;
}
res.json({
username: req.params.username,
message: 'Delete User Successful'
});
log.info(`${req.params.username} has been deleted`);
});
});
/** * @api {post} /v1/auth/changepassword User change password * @apiName UserChangePassword * @apiGroup userAuthentication * * @apiParam {String} username User's name. * @apiParam {String} oldpassword User's old password. * @apiParam {String} newpassword User's old password. * * @apiSuccess {String} username The username of the user. * @apiSuccess {string} message The message if changing password successful. * * @apiSuccessExample Success-Response: * HTTP/1.1 200 OK * { * "username": "test", * "message": "change password successful" * } * * @apiError AUTHENTICATE_FAILURE The register failure. * * @apiErrorExample Error-Response: * HTTP/1.1 401 Unauthorized * { * "err": "AUTHENTICATE_FAILURE", * "message": "Password or username is incorrect" * } */
router.post('/changepassword', function(req, res) {
User.findOne({ 'username': req.body.username }, (err, user) => {
if (err) {
log.error(err);
res.status(500).json({
err: 'SERVER_ERROR',
message: COMM_ERR.SERVER_ERROR
});
return;
}
if (!user) {
res.status(500).json({
err: 'USER_NOT_EXIST',
message: AUTH_ERR.USER_NOT_EXIST
});
return;
}
user.changePassword(req.body.oldpassword, req.body.newpassword, (err, value) => {
if (err) {
log.error(err);
res.status(401).json({
err: 'AUTHENTICATE_FAILURE',
message: err.message
});
return;
}
log.info(`${req.body.username} change password successful`);
res.json({
username: req.body.username,
message: 'change password successful'
});
});
});
});
/** * @api {get} /v1/auth/logout User login out * @apiName UserLogout * @apiGroup userAuthentication * * @apiSuccess {String} username The username of the user. * @apiSuccess {string} message The message if user login out successful. * * @apiSuccessExample Success-Response: * HTTP/1.1 200 OK * { * "username": "test", * "message": "logout successful" * } * * @apiError NOT_LOGIN There is no user logon in. * * @apiErrorExample Error-Response: * HTTP/1.1 401 Unauthorized * { * "err": "NOT_LOGIN", * "message": "No user has been logon" * } */
router.get('/logout', function(req, res) {
const user = req.user;
if (!user) {
res.status(401).json({
err: 'NOT_LOGIN',
message: 'No user has been logon'
});
return;
}
// user login out
req.logout();
if (!req.user) {
res.json({
username: user.username,
message: 'logout successful'
});
log.info(`${user.username} has been logon out`);
return;
}
res.status(500).json({
err: 'SERVER_ERROR',
message: 'logout failure!'
});
});
function isAhenticated(req, res, next) {
User.findOne({ 'username': req.body.username }, (err, user) => {
if (err) {
log.error(err);
res.json({
err: 'SERVER_ERROR',
message: COMM_ERR.SERVER_ERROR
});
return;
}
// If user is not existed
if (!user) {
res.json({
err: 'USER_NOT_EXIST',
message: AUTH_ERR.USER_NOT_EXIST
});
return;
}
user.authenticate(req.body.password, (err, value) => {
if (err) {
log.error(err);
res.json({
err: 'SERVER_ERROR',
message: COMM_ERR.SERVER_ERROR
});
} else if (value) {
return next();
} else {
res.json({
err: 'AUTHENTICATE_FAILURE',
message: AUTH_ERR.AUTHENTICATE_FAILURE
});
}
});
});
}
module.exports = router;
复制代码
这是一套常见的有关用户登陆注册验证的接口github
由于文本只涉及到这个模块,因此将这个模块的接口都写在userAuthentication
测试套件下web
describe('userAuthentication', function() {}
复制代码
'use strict';
const request = require('supertest');
const url = 'http://localhost:5001';
// eslint-disable-next-line no-unused-vars
const should = require('should');
var userCookie;
// 用户名密码
const user = {
username: 'name',
password: 'password'
};
// 测试更改密码(每次测试完调换)
const user2 = {
username: 'uu2',
password: 'oldpassword'
};
const newUser2 = {
username: 'uu2',
oldpassword: 'oldpassword',
newpassword: 'newpassword'
};
// const user22={
// username: 'uu2',
// password: 'newpassword'
// };
// const oldUser2 = {
// username: 'uu2',
// oldpassword: 'newpassword',
// newpassword: 'oldpassword'
// };
describe('userAuthentication', function() {
// 测试注册接口
describe('UserRegister', function() {
describe('POST /register', function() {
// eslint-disable-next-line max-len
it('register success', function(done) {
request(url)
.post('/api/v1/auth/register')
.send(user)
.expect(200)
.end(function(err, res) {
res.body.should.containEql({
message: 'User registered successful'
});
if (err) throw err;
done();
});
});
it('repeated registration failure.', function(done) {
request(url)
.post('/api/v1/auth/register')
.send(user)
.expect(500)
.end(function(err, res) {
res.body.should.containEql({
err: 'REGISTER_FAILURE'
});
if (err) throw err;
done();
});
});
});
});
// 测试登陆接口
describe('UserLogin', function() {
describe('POST /login', function() {
it('login success', function(done) {
request(url)
.post('/api/v1/auth/login')
.send(user)
.expect(200)
.end(function(err, res) {
res.body.should.containEql({
message: 'Authentication Success'
});
if (err) throw err;
done();
});
});
it('USER_NOT_EXIST.', function(done) {
request(url)
.post('/api/v1/auth/login')
.send({
username: 'a',
password: 'admin'
})
.expect(200)
.end(function(err, res) {
res.body.should.containEql({
err: 'USER_NOT_EXIST'
});
if (err) throw err;
done();
});
});
});
});
// 权限验证
describe('UserAuthInfo', function() {
describe('GET /api/v1/auth/', function() {
// 没有登陆,权限验证
it('The current User was not login.', function(done) {
request(url)
.get('/api/v1/auth/')
.set('Accept', 'application/json')
.expect('Content-Type', /json/)
.expect(401)
.end(function(err, res) {
res.body.should.containEql({
err: 'NOT_LOGIN'
});
if (err) throw err;
done();
});
});
// 权限验证前先登陆
beforeEach(function(done) {
request(url)
.post('/api/v1/auth/login')
.send(user)
.set('Accept', 'application/json')
.end(function(err, res) {
if (!err) {
userCookie = res.header['set-cookie'];
done();
}
});
});
it('The username of the current user.', function(done) {
request(url)
.get('/api/v1/auth/')
.set('Cookie', userCookie)
.expect(200)
.end(function(err, res) {
res.body.should.have.keys('username');
if (err) throw err;
done();
});
});
});
});
// 测试用户注销接口
describe('UserLogout', function() {
describe('GET /logout', function() {
// 没有登陆,测试注销
it('NOT_LOGIN.', function(done) {
request(url)
.get('/api/v1/auth/logout')
.expect(401)
.end(function(err, res) {
res.body.should.containEql({
err: 'NOT_LOGIN'
});
if (err) throw err;
done();
});
});
// 注销成功前先登陆
beforeEach(function(done) {
request(url)
.post('/api/v1/auth/login')
.send(user)
.set('Accept', 'application/json')
.end(function(err, res) {
if (!err) {
userCookie = res.header['set-cookie'];
done();
}
});
});
it('logout successful.', function(done) {
request(url)
.get('/api/v1/auth/logout')
.set('Cookie', userCookie)
.expect(200)
.end(function(err, res) {
res.body.should.containEql({
message: 'logout successful'
});
if (err) throw err;
done();
});
});
});
});
// 测试更改用户密码接口
describe('UserChangePassword', function() {
describe('POST /changepassword', function() {
// 更改用户密码前先注册-登陆
// eslint-disable-next-line no-undef
before(function(done) {
request(url)
.post('/api/v1/auth/register')
.send(user2)
.end(function(err, res) {
if (err) throw err;
done();
});
});
// eslint-disable-next-line no-undef
before(function(done) {
request(url)
.post('/api/v1/auth/login')
.send(user2)
.set('Accept', 'application/json')
.end(function(err, res) {
if (!err) {
userCookie = res.header['set-cookie'];
done();
}
});
});
it('change password successful', function(done) {
request(url)
.post('/api/v1/auth/changepassword')
.set('Cookie', userCookie)
.send(newUser2)
.expect(200)
.end(function(err, res) {
res.body.should.containEql({
message: 'change password successful'
});
if (err) throw err;
done();
});
});
it('AUTHENTICATE_FAILURE', function(done) {
request(url)
.post('/api/v1/auth/changepassword')
.set('Cookie', userCookie)
.send(newUser2)
.expect(401)
.end(function(err, res) {
res.body.should.containEql({
err: 'AUTHENTICATE_FAILURE'
});
if (err) throw err;
done();
});
});
// after(function(done) {
// request(url)
// .post('/api/v1/auth/login')
// .send(user22)
// .set('Accept', 'application/json')
// .end(function(err, res) {
// if (!err) {
// userCookie = res.header['set-cookie'];
// done();
// }
// });
// });
// after(function(done) {
// request(url)
// .post('/api/v1/auth/changepassword')
// .set('Cookie', userCookie)
// .send(oldUser2)
// .expect(200)
// .end(function(err, res) {
// res.body.should.containEql({
// message: 'rechange password successful'
// });
// if (err) throw err;
// done();
// });
// });
});
});
// 测试删除用户接口
describe('UserDelete', function() {
describe('DELETE /user/:username', function() {
it('NOT_LOGIN.', function(done) {
request(url)
.delete(`/api/v1/auth/user/${user.username}`)
.expect(401)
.end(function(err, res) {
res.body.should.containEql({
err: 'NOT_LOGIN'
});
if (err) throw err;
done();
});
});
// 删除用户前先登陆
beforeEach(function(done) {
request(url)
.post('/api/v1/auth/login')
.send(user)
.set('Accept', 'application/json')
.end(function(err, res) {
if (!err) {
userCookie = res.header['set-cookie'];
done();
}
});
});
it('delete user success', function(done) {
request(url)
.delete(`/api/v1/auth/user/${user.username}`)
.set('Cookie', userCookie)
.expect(200)
.end(function(err, res) {
res.body.should.containEql({
message: 'Delete User Successful'
});
if (err) throw err;
done();
});
});
});
});
});
复制代码
所谓"测试框架",就是运行测试的工具。经过它,能够为JavaScript应用添加测试,从而保证代码的质量。
一般应用会有单元测试(Unit tests)和功能测试(Functional tests),复杂大型应用可能会有整合测试(Integration tests)。
开发人员主要是集中单元测试,做为开发中的反馈。
单元测试的好处:
单元测试应该:简单,快速执行,清晰的错误报告。 测试框架基本上都作了同一件事儿:
选择框架会考虑下面的点:
其实都是先写测试代码,感受BDD 风格更人性。
组合使用工具很常见,即便已选框架也能实现相似的功能
解释上面提到的点:
Jest
Jasmine
Mocha
综上所述,Mocha 用的人最多,社区最成熟,灵活,可配置性强易拓展,Jest 开箱即用,里边啥都有提供全面的方案,Tape 最精简,提供最基础的东西最底层的API。因此本文就选择用mocha。
Mocha自己是不包含断言库的,因此咱们须要本身选择断言库。should是一个很简单的、贴近天然语言的断言库。固然,Mocha是适配全部的断言库的,若是你喜欢其余的断言库好比expect之类的,你也能够把它包含进来使用。
单单使用Mocha和should就几乎能够知足全部JavaScript函数的单元测试。可是对于Node应用而言,不只仅是函数的集合,好比一个web应用的测试。这时候就须要配合一个http代理,完成Http请求和路由的测试。 Supertest是一个HTTP代理服务引擎,能够模拟一切HTTP请求行为。Supertest能够搭配任意的应用框架,从而进行应用的单元测试。
describe块称为"测试套件"(test suite),表示一组相关的测试。它是一个函数,第一个参数是测试套件的名称("加法函数的测试"),第二个参数是一个实际执行的函数。
it块称为"测试用例"(test case),表示一个单独的测试,是测试的最小单位。它也是一个函数,第一个参数是测试用例的名称("1 加 1 应该等于 2"),第二个参数是一个实际执行的函数。
Mocha在describe块之中,提供测试用例的四个钩子:before()、after()、beforeEach()和afterEach()。它们会在指定时间执行。
describe('hooks', function() {
before(function() {
// 在本区块的全部测试用例以前执行
});
after(function() {
// 在本区块的全部测试用例以后执行
});
beforeEach(function() {
// 在本区块的每一个测试用例以前执行
});
afterEach(function() {
// 在本区块的每一个测试用例以后执行
});
// test cases
});
复制代码
安装mocha> = v3.0.0,npm的版本应该> = v2.14.2。除此,确保使用Node.js的版本> = v4来运行mocha
做为项目的依赖进行安装
npm install --save-dev mocha
复制代码
mkdir test
cd test
touch test.js
复制代码
加入测试代码
'use strict'
var assert = require('assert');
describe('Array', function() {
describe('#indexOf()', function() {
it('should return 0 when the value is not present', function() {
assert.equal([1, 2, 3].indexOf(1), 1);
});
});
});
复制代码
安装依赖
npm install --save-dev assert
复制代码
执行测试
./node_modules/mocha/bin/mocha
复制代码
报错结果
Array
#indexOf()
1) should return 0 when the value is not present
0 passing (5ms)
1 failing
1) Array
#indexOf()
should return 0 when the value is not present:
AssertionError [ERR_ASSERTION]: 0 == 1
+ expected - actual
-0
+1
at Context.<anonymous> (test/test.js:6:14)
复制代码
package.json中写入命令
"mocha": "mocha"
复制代码
执行命令
npm run mocha
复制代码
正确测试
'use strict'
var assert = require('assert');
describe('Array', function() {
describe('#indexOf()', function() {
it('should return 0 when the value is not present', function() {
assert.equal([1, 2, 3].indexOf(1), 0);
});
});
});
复制代码
正确结果
Array
#indexOf()
✓ should return 0 when the value is not present
1 passing (4ms)
复制代码
到这里,对mocha就有了初步的认识
了解了背景和框架后,正式开启测试
npm install --save-dev mocha mochawesome should supertest
复制代码
"mochawesome": "./node_modules/.bin/mocha --reporter mochawesome",
"dev": "node index.js"
复制代码
mochawesome生成报告
dev启动项目
/** * @api {post} /v1/auth/register User Register * @apiName UserRegister * @apiGroup userAuthentication * * @apiParam {String} username New user's name. * @apiParam {String} password New user's password. * * @apiSuccess {String} username The username of the register user. * @apiSuccess {string} message The registering success info. * * @apiSuccessExample Success-Response: * HTTP/1.1 200 OK * { * "username": "gushen", * "message": "User registered successful" * } * * @apiError REGISTER_FAILURE The register failure. * * @apiErrorExample Error-Response: * HTTP/1.1 500 Internal Server Error * { * "err": "REGISTER_FAILURE", * "message": "User register failure!" * } */
router.post('/register', function(req, res, next) {
User.register(new User({ username: req.body.username }), req.body.password, function(err) {
if (err) {
log.error(err);
res.status(500).json({
err: 'REGISTER_FAILURE',
message: AUTH_ERR.REGISTER_FAILURE
});
return;
}
log.info('user ' + req.body.username + ' registered successful!');
res.json({
username: req.body.username,
message: 'User registered successful'
});
});
});
复制代码
UserRegister
是第二层套件POST /register
是第三层套件register success
是测试用例名称注意: 每一个测试用例结束后必须带上done
,不然没有结束标识,会超时报错
// 测试注册接口
describe('UserRegister', function() {
describe('POST /register', function() {
// eslint-disable-next-line max-len
it('register success', function(done) {
request(url)
.post('/api/v1/auth/register')
.send(user)
.expect(200)
.end(function(err, res) {
res.body.should.containEql({
message: 'User registered successful'
});
if (err) throw err;
done();
});
});
it('repeated registration failure.', function(done) {
request(url)
.post('/api/v1/auth/register')
.send(user)
.expect(500)
.end(function(err, res) {
res.body.should.containEql({
err: 'REGISTER_FAILURE'
});
if (err) throw err;
done();
});
});
});
});
复制代码
没什么好讲的,同测试注册接口步骤一致
describe('UserLogin', function() {
describe('POST /login', function() {
it('login success', function(done) {
request(url)
.post('/api/v1/auth/login')
.send(user)
.expect(200)
.end(function(err, res) {
res.body.should.containEql({
message: 'Authentication Success'
});
if (err) throw err;
done();
});
});
it('USER_NOT_EXIST.', function(done) {
request(url)
.post('/api/v1/auth/login')
.send({
username: 'a',
password: 'admin'
})
.expect(200)
.end(function(err, res) {
res.body.should.containEql({
err: 'USER_NOT_EXIST'
});
if (err) throw err;
done();
});
});
});
});
复制代码
before
钩子中加入userCookie = res.header['set-cookie'];
复制代码
Cookie
.set('Cookie', userCookie)
复制代码
// 权限验证
describe('UserAuthInfo', function() {
describe('GET /api/v1/auth/', function() {
// 没有登陆,权限验证
it('The current User was not login.', function(done) {
request(url)
.get('/api/v1/auth/')
.set('Accept', 'application/json')
.expect('Content-Type', /json/)
.expect(401)
.end(function(err, res) {
res.body.should.containEql({
err: 'NOT_LOGIN'
});
if (err) throw err;
done();
});
});
// 权限验证前先登陆
beforeEach(function(done) {
request(url)
.post('/api/v1/auth/login')
.send(user)
.set('Accept', 'application/json')
.end(function(err, res) {
if (!err) {
userCookie = res.header['set-cookie'];
done();
}
});
});
it('The username of the current user.', function(done) {
request(url)
.get('/api/v1/auth/')
.set('Cookie', userCookie)
.expect(200)
.end(function(err, res) {
res.body.should.have.keys('username');
if (err) throw err;
done();
});
});
});
});
复制代码
没什么好讲的,同测试权限验证步骤一致
describe('UserLogout', function() {
describe('GET /logout', function() {
// 没有登陆,测试注销
it('NOT_LOGIN.', function(done) {
request(url)
.get('/api/v1/auth/logout')
.expect(401)
.end(function(err, res) {
res.body.should.containEql({
err: 'NOT_LOGIN'
});
if (err) throw err;
done();
});
});
// 注销成功前先登陆
beforeEach(function(done) {
request(url)
.post('/api/v1/auth/login')
.send(user)
.set('Accept', 'application/json')
.end(function(err, res) {
if (!err) {
userCookie = res.header['set-cookie'];
done();
}
});
});
it('logout successful.', function(done) {
request(url)
.get('/api/v1/auth/logout')
.set('Cookie', userCookie)
.expect(200)
.end(function(err, res) {
res.body.should.containEql({
message: 'logout successful'
});
if (err) throw err;
done();
});
});
});
});
复制代码
更改用户密码前先注册-登陆
// 测试更改用户密码接口
describe('UserChangePassword', function() {
describe('POST /changepassword', function() {
// 更改用户密码前先注册-登陆
// eslint-disable-next-line no-undef
before(function(done) {
request(url)
.post('/api/v1/auth/register')
.send(user2)
.end(function(err, res) {
if (err) throw err;
done();
});
});
// eslint-disable-next-line no-undef
before(function(done) {
request(url)
.post('/api/v1/auth/login')
.send(user2)
.set('Accept', 'application/json')
.end(function(err, res) {
if (!err) {
userCookie = res.header['set-cookie'];
done();
}
});
});
it('change password successful', function(done) {
request(url)
.post('/api/v1/auth/changepassword')
.set('Cookie', userCookie)
.send(newUser2)
.expect(200)
.end(function(err, res) {
res.body.should.containEql({
message: 'change password successful'
});
if (err) throw err;
done();
});
});
it('AUTHENTICATE_FAILURE', function(done) {
request(url)
.post('/api/v1/auth/changepassword')
.set('Cookie', userCookie)
.send(newUser2)
.expect(401)
.end(function(err, res) {
res.body.should.containEql({
err: 'AUTHENTICATE_FAILURE'
});
if (err) throw err;
done();
});
});
// after(function(done) {
// request(url)
// .post('/api/v1/auth/login')
// .send(user22)
// .set('Accept', 'application/json')
// .end(function(err, res) {
// if (!err) {
// userCookie = res.header['set-cookie'];
// done();
// }
// });
// });
// after(function(done) {
// request(url)
// .post('/api/v1/auth/changepassword')
// .set('Cookie', userCookie)
// .send(oldUser2)
// .expect(200)
// .end(function(err, res) {
// res.body.should.containEql({
// message: 'rechange password successful'
// });
// if (err) throw err;
// done();
// });
// });
});
});
复制代码
问题是我改完后得将密码改回来,这一步我没有成功,很奇怪为何?
目前得每次测试完后将新旧密码调换,真的很麻烦
没什么好讲的,同测试权限验证步骤一致
describe('UserDelete', function() {
describe('DELETE /user/:username', function() {
it('NOT_LOGIN.', function(done) {
request(url)
.delete(`/api/v1/auth/user/${user.username}`)
.expect(401)
.end(function(err, res) {
res.body.should.containEql({
err: 'NOT_LOGIN'
});
if (err) throw err;
done();
});
});
// 删除用户前先登陆
beforeEach(function(done) {
request(url)
.post('/api/v1/auth/login')
.send(user)
.set('Accept', 'application/json')
.end(function(err, res) {
if (!err) {
userCookie = res.header['set-cookie'];
done();
}
});
});
it('delete user success', function(done) {
request(url)
.delete(`/api/v1/auth/user/${user.username}`)
.set('Cookie', userCookie)
.expect(200)
.end(function(err, res) {
res.body.should.containEql({
message: 'Delete User Successful'
});
if (err) throw err;
done();
});
});
});
});
复制代码
口渴了,快去喝杯mocha吧
node中使用 mocha + supertest + should 来写单元测试
【Node开发笔记】单元测试工具Mocha和SuperTest
一步一步搭建react应用-node中使用 mocha + supertest + should 来写单元测试
mocha + chai + supertest 测试 node server
最后,别忘了给这个项目点一个star哦,谢谢支持。
一个学习编程技术的公众号。天天推送高质量的优秀博文、开源项目、实用工具、面试技巧、编程学习资源等等。目标是作到我的技术与公众号一块儿成长。欢迎你们关注,一块儿进步,走向全栈大佬的修炼之路