Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves

I have this test of nodejs when testing I get a error of done function not declared.

Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. 

My test code is, I have the done call back but still getting the error to call the done();

    it('remove existing subdocument', (done) => {     const Vic = new User({       name: 'Vic',       posts: [{ title: 'Leaning Nodejs' }]     });      vic.save()       .then(() => User.findOne({ name: 'Vic' }))       .then((user) => {         const post = user.posts[0];         post.remove();         return user.save();       })       .then(() => User.findOne({ name: 'Vic' }))       .then((user) => {         assert(user.posts.length === 0);         done();       });   }); 
like image 476
G B Avatar asked May 24 '17 04:05

G B


2 Answers

I know an ugly way of doing it, just by increasing default timeout of Mocha from 2 seconds to 10 seconds this can be done by adding a flag --timeout 10000 in the test scripts i.e -

package.json

 "scripts": {     "start": "SET NODE_ENV=dev && node server.js",     "test": "mocha --timeout 10000"   } 
like image 75
Sabunkar Tejas Sahailesh Avatar answered Nov 10 '22 01:11

Sabunkar Tejas Sahailesh


I was facing the same issue, @MFAL's link in comment helped. I am expanding upon it.

When there is an error/incorrect assertion an error is raised inside the promise. This leads to promise rejection. Once rejected done is never called and mocha reports time out. I solved this by writing a .catch block and chaining it with the promise:

          it('resolves', (done) => {             fooAsyncPromise(arg1, arg2).then((res, body) => {                 expect(res.statusCode).equal(incorrectValue);                 done();             }).catch(done);          }); 

Other ways as mentioned in the Wietse's blog are:

To chain a then(done, done) which handles both resolve and reject of the promise.

         it('resolves', (done) => {            resolvingPromise.then( (result) => {              expect(result).to.equal('promise resolved');            }).then(done, done);          }); 

Return a promise:

        it('resolves', () => {           return resolvingPromise.then( (result) => {             expect(result).to.equal('promise resolved');           });         }); 

Use async/wait:

        it('assertion success', async () => {           const result = await resolvingPromise;           expect(result).to.equal('promise resolved');          }); 
like image 37
avck Avatar answered Nov 10 '22 01:11

avck