所以我现在已经在我的这个项目上工作了一段时间,但是我永远无法真正弄清楚如何使我的测试生效。我尝试过以各种不同的方式测试我的API,但是每次更改内容时,似乎只会遇到更多问题。在这一点上,我很沮丧,我需要一些新鲜的眼睛来检查一下。
仅供参考,API实际上可以正常工作,我可以调用所有路由并毫无问题地获得正确的结果,我一直在使用httpie来进行“测试”,而无需实际编写任何测试。
无论如何,这是我一直在运行的一些代码:
const chai = require('chai');
const expect = chai.expect;
const superagent = require('superagent');
const User = require('../model/User.js');
const url = process.env.API_URL;
const testUser = {
email: 'exampleuser@test.com',
password: '123'
};
const newUser = {
email: 'newuser@test.com',
password: '321'
};
describe('POST: /api/signup', () => {
describe('with valid credentials', () => {
afterEach(() => User.deleteOne({'email': testUser.email}));
console.log(`${url}/api/signup`);
it('should return a status code of 200', () => {
superagent.post(`${url}/api/signup`)
.send(testUser)
.then((res) => {
expect(res).to.be.an('object');
expect(res.status).to.equal(200);
})
.catch((err) => console.error(err));
});
});
});
我也尝试使用done,它看起来像这样:
describe('POST: /api/signup', () => {
describe('with valid credentials', () => {
afterEach((done) => {
User.deleteOne({'email': testUser.email})
.then(() => done())
.catch((err) => done(err));
});
console.log(`${url}/api/signup`);
it('should return a status code of 200', (done) => {
superagent.post(`${url}/api/signup`)
.send(testUser)
.end((res, err) => {
if(err) return done(err);
expect(res).to.be.an('object');
expect(res.status).to.equal(200);
})
.then(() => done())
.catch((err) => console.error(err));
});
});
});
但是每次我运行它时,您都可以看到它完成了测试并转到下一个情况,然后调用并返回所有内容:
Backend-Portfolio:server.js running on port: 8000 +0ms
USER_ROUTES
POST: /api/signup
with valid credentials
1) should return a status code of 200
Backend-Portfolio:user-router.js POST: /api/signup +0ms
2) "after each" hook for "should return a status code of 200"
GET: /api/login
with valid credentials
Backend-Portfolio:user-router.js POST: /api/signup +2s
Backend-Portfolio:user-router.js setting up new user +50ms
Backend-Portfolio:User.js generatePasswordHash:normal +0ms
Backend-Portfolio:User.js generateToken +158ms
Backend-Portfolio:User.js generateFindHash +1ms
Backend-Portfolio:user-router.js setting up new user +462ms
Backend-Portfolio:User.js generatePasswordHash:normal +295ms
Backend-Portfolio:User.js generateToken +101ms
Backend-Portfolio:User.js generateFindHash +0ms
如果有人好奇,这里是路线和调用的方法:
您可以在这里看到方法链的调用位置,我将这条路线变成了一个承诺,只是尝试使用另一种测试方法。
userRouter.post('/api/signup', jsonParser, (req, res) => {
debug('POST: /api/signup');
let password = req.body.password;
delete req.body.password;
return new Promise((resolve, reject) => {
User.findOne({'email': req.body.email})
.then((user) => {
if(user){
if(user.authenticated){
// NOTE: maybe update all error codes and texts to be very specific
reject(createError(400, 'this email is already used, please log in with your password'));
}else{
user.generatePasswordHash('normal', password)
.then((user) => user.generateToken())
.then((token) => resolve(res.json(token)))
.catch((err) => reject(console.error(err)));
}
}
else{
debug('setting up new user');
let user = new User({
googlePermissions: {authenticated: false, password: null},
facebookPermissions: {authenticated: false, password: null},
twitterPermissions: {authenticated: false, password: null},
authenticated: true,
email: req.body.email
});
user.generatePasswordHash('normal', password)
.then((user) => user.generateToken())
.then((token) => resolve(res.json(token)))
.catch((err) => reject(console.error(err)));
}
})
.catch((err) => reject(console.error(err)));
});
});
剩下的事情可能有点多余,但是可以了:
generatePasswordHash:
userSchema.methods.generatePasswordHash = function(type, password){
debug(`generatePasswordHash:${type}`);
return new Promise((resolve, reject) => {
if(!password) reject(createError(400, 'no password was provided'));
bcrypt.hash(password, 10, (err, hash) => {
if(err) return reject(err);
switch(type){
case 'normal':
this.password = hash;
resolve(this);
break;
case 'googlePermissions':
this.googlePermissions.password = hash;
resolve(this);
break;
case 'facebookPermissions':
this.facebookPermissions.password = hash;
resolve(this);
break;
case 'twitterPermissions':
this.twitterPermissions.password = hash;
resolve(this);
break;
default:
return reject(createError(400, `unrecognized password type: ${type}`));
}
});
});
};
generateToken:
userSchema.methods.generateToken = function(){
debug('generateToken');
return new Promise((resolve, reject) => {
this.generateFindHash()
.then((findHash) => resolve(jsonwebtoken.sign({token: findHash}, process.env.APP_SECRET)))
.catch((err) => reject(err));
});
};
generateFindHash:
userSchema.methods.generateFindHash = function(){
debug('generateFindHash');
return new Promise((resolve, reject) => {
this.findHash = crypto.randomBytes(32).toString('hex');
this.save()
.then(() => resolve(this.findHash))
.catch((err) => reject(err));
});
};
感谢到目前为止取得成功的任何人。