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哦,謝謝支持。
一個學習編程技術的公衆號。天天推送高質量的優秀博文、開源項目、實用工具、面試技巧、編程學習資源等等。目標是作到我的技術與公衆號一塊兒成長。歡迎你們關注,一塊兒進步,走向全棧大佬的修煉之路