我目前正在使用mocha,chai和sinon测试此代码
import passport from 'passport';
import jwt from 'jsonwebtoken';
import expressJwt from 'express-jwt';
import compose from 'composable-middleware';
import User from '../apis/user/user.model';
import config from '../../config/app';
const validateJwt = expressJwt({
secret: config.auth.secret
});
export function signToken(id, role) {
return jwt.sign({ id, role }, config.auth.secret, {
expiresIn: config.auth.expiresIn
});
}
export function setTokenCookie(req, res) {
if (!req.user)
return res.status(404)
.json({
message: "It looks like you aren't logged in, please try again"
});
const token = signToken(req.user.id, req.user.role);
res.cookie('token', token);
res.redirect('/');
}
export function isAuthenticated() {
return compose()
.use((req, res, next) => validateJwt(req, res, next))
.use((req, res, next) => {
User.get(req.user.id)
.then(user => {
req.user = user;
next();
}, () => {
return res.status(404).json({
message: 'User not found, please try to login again'
});
})
.catch(err => next(err));
});
}
export function hasRole(role) {
return compose()
.use(isAuthenticated())
.use((req, res, next) => {
if (req.user.role === role) {
next();
} else {
res.status(403).json({
message: "You don't have the right privilege to access this resource"
});
}
});
}
这是测试文件
import request from 'supertest';
import app from '../main';
import User from '../apis/user/user.model';
import { hasRole } from './auth.service';
describe('Auth Service', () => {
let user, admin;
before(done => {
const _user = {
username: 'user',
email: 'user@user.com',
password: 'user'
};
const _admin = {
username: 'admin',
email: 'admin@admin.com',
password: 'admin',
role: 'admin'
};
User.delete().execute()
.then(() => {
return User.save([_user, _admin]);
})
.then(users => {
user = users[0];
admin = users[1];
done();
});
});
after(done => {
User.delete().execute()
.then(() => done());
});
describe('hasRole', () => {
it('should call res.status with 403 and send message if the user does not have the right access', done => {
const token = signToken(user.id, user.role);
const reqStub = {
headers: {
authorization: `Bearer ${token}`
}
};
const statusSpy = spy();
const jsonSpy = spy();
const resStub = {
status(statusCode) {
statusSpy(statusCode);
return {
json: jsonSpy
};
}
};
const nextSpy = spy();
Object.observe(statusSpy, changes => {
if (changes[0].name === 'called') {
expect(statusSpy.args[0][0]).to.equal(403);
expect(jsonSpy).to.have.been.calledOnce;
expect(jsonSpy.args[0][0].message).to.equal("You don't have the right privilege to access this resource");
done();
}
});
hasRole('admin')(reqStub, resStub, nextSpy);
// This particular test sometimes does not work
// This setTimeout is just a reminder
setTimeout(() => {
done(new Error('Sometimes this does not work, please investigate'));
}, 1500);
});
});
});
我运行此测试,50%的时间通过,50%的时间失败 . 当它出错并且我在Object.observe回调函数中的console.log时,它甚至都没有记录 .
如果Object.observe方法不起作用,那么测试此函数hasRole的最佳方法是什么,而不重构函数本身 . 理想情况下,我想要像spy.on('被叫')这样的东西,但是sinon没有那个