Так что я уже некоторое время работаю над этим проектом, но я так и не смог понять, как заставить мое тестирование работать.Я пытался протестировать свой 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));
});
});
});
Я пытался использоватьСделано также, это выглядело примерно так:
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));
});
};
Спасибо всем, кто сделал это так далеко.