异步功能在摩卡之前()总是在它()规范之前完成?

我在 before()中有一个回调函数,用于清理数据库。 before()中的所有内容是否保证在 it()开始之前完成?

before(function(){
db.collection('user').remove({}, function(res){}); // is it guaranteed to finish before it()?
});


it('test spec', function(done){
// do the test
});


after(function(){
});
71829 次浏览

For new mocha versions :

You can now return a promise to mocha, and mocha will wait for it to complete before proceeding. For example, the following test will pass :

let a = 0;
before(() => {
return new Promise((resolve) => {
setTimeout(() => {
a = 1;
resolve();
}, 200);
});
});
it('a should be set to 1', () => {
assert(a === 1);
});

You can find the documentation here

For older mocha versions :

If you want your asynchronous request to be completed before everything else happens, you need to use the done parameter in your before request, and call it in the callback.

Mocha will then wait until done is called to start processing the following blocks.

before(function (done) {
db.collection('user').remove({}, function (res) { done(); }); // It is now guaranteed to finish before 'it' starts.
})


it('test spec', function (done) {
// execute test
});


after(function() {});

You should be careful though, as not stubbing the database for unit testing may strongly slow the execution, as requests in a database may be pretty long compared to simple code execution.

For more information, see the Mocha documentation.

Hopefully your db.collection() should return a promise. If yes then you can also use async keyword in before()

// Note: I am using Mocha 5.2.0.
before(async function(){
await db.collection('user').remove({}, function(res){}); // it is now guaranteed to finish before it()
});

you can use an IIFE (Immediately Invoked Function Expression).

Here is an example:

before(function () {
(async () => {
try {
await mongoose.connect(mongo.url, { useNewUrlParser: true, useUnifiedTopology: true });
} catch (err) {
console.log(err);
}
})();
});