Gir*_*pta 2 bdd mocha.js node.js supertest
我需要在mocha中的before()钩子中做多个异步调用.我需要删除用户,然后注册,验证电子邮件,最后登录以获取令牌以验证所有其他测试用例.这是我的代码片段:
const userInfo = {
"password": "pass123",
"email": "test@email.com",
};
var token = '' , userId = '';
before((done) => {
// Delete the user if already exists
User.remove({
email: userInfo.email
}).then((res) => {
// console.log(res.result);
})
.end(done);
done();
});
before((done) => {
request(app)
.post('/api/users')
.send(userInfo)
.expect(200)
.expect((res) => {
})
.end(done);
});
before((done) => {
User.findOne({
email: userInfo.email
}).then((res) => {
userId = res._id;
request(app)
.post('/api/users/verify-email')
.send({'token' : userId})
.expect(200)
.expect((res) => {
})
.end(done);
})
.end(done);
done();
});
Run Code Online (Sandbox Code Playgroud)
这些调用不是按顺序执行的.我需要在验证电子邮件之前获取userId,但我收到以下错误:
POST /api/users/verify-email 401 4.082 ms - 45
1) "before all" hook
Run Code Online (Sandbox Code Playgroud)
首先,是的,mocha允许多个挂钩,并保证以正确的顺序调用它们.要确保这一点,您可以运行此代码段.
'use strict';
const results = [];
const assert = require('assert');
before(done => {
setTimeout(() => {
console.log(`First 'before'`);
results.push(1);
done(); //Will be called last
}, 1000)
});
before(done => {
setTimeout(() => {
console.log(`Second 'before'`);
results.push(2); //Will be called second
done();
}, 300)
});
before(done => {
setTimeout(() => {
console.log(`Third 'before'`);
results.push(3); //Will be called first
done();
}, 100)
});
describe('Before hooks order', () => {
it('should before hooks sequentially', () => {
//Check if the hooks were called in the right order anyway
assert.deepEqual(results, [1, 2, 3]);
});
});
//Output is:
// First 'before'
// Second 'before'
// Third 'before'Run Code Online (Sandbox Code Playgroud)
但为了实现这一点,只有在完成所有异步操作以让mocha知道钩子已完成且它应该运行下一个时,才需要调用done().
还有一个规则是任何Node.js回调只能被调用一次.所以这里有几个修复:
before((done) => {
// Delete the user if already exists
User
.remove({
email: userInfo.email
})
.then((res) => {
// console.log(res.result);
})
.end(done);
//Do not call done here() because User.remove have only started
//We need to wait until it finishes. Done will be called in .end method
// done();
});
before((done) => {
//All good here
request(app)
.post('/api/users')
.send(userInfo)
.expect(200)
.expect((res) => {
})
.end(done);
});
before((done) => {
User.findOne({
email: userInfo.email
}).then((res) => {
userId = res._id;
//You need a return statement here so the outer promise waits
//Until the internal call finishes
return request(app)
.post('/api/users/verify-email')
.send({'token': userId})
.expect(200)
.expect((res) => {
});
//We must not call callback multiple times, so remove this.
// .end(done);
})
//Now this 'end' will happen only after both calls finish
.end(done);
//Remove this please, for the same reason as with the first 'before'
// done();
});Run Code Online (Sandbox Code Playgroud)
请检查一下.我无法运行你的代码(没有你的api),所以请告诉我任何问题.