For asynchronous tests and interceptors, make sure to call "done ()"; if return promise, make sure it resolved

I have this nodejs test while testing. I am getting the error of a function done 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: I have a callback done but still get an error to call 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();
      });
  });

      

+24


source to share


5 answers


I faced the same problem, @MFAL link in the comment helped. I am expanding on this.

If there is an error / invalid statement in the promise, an error is raised. This leads to the rejection of promises. Once rejected, it is never called and the mocha reports a timeout. I solved it by writing a block .catch

and .catch

its promise:

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

      

Other ways mentioned in the Wietse blog :

A chain then(done, done)

that handles both the decision and the rejection of a 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 / await:

        it('assertion success', async () => {
          const result = await resolvingPromise;
          expect(result).to.equal('promise resolved'); 
        });

      

+21


source


I know a horrible way to do this by simply increasing the default Mocha timeout from 2 seconds to 10 seconds, this can be done by adding the --timeout 10000 flag to the test scripts i.e.

package.json



 "scripts": {
    "start": "SET NODE_ENV=dev && node server.js",
    "test": "mocha --timeout 10000"
  }

      

+19


source


in your package.json file you can fix this error using --timeout 1500 as I am using below.

"scripts": {
  "start": "node server/server.js",
  "test": "export NODE_ENV=test || SET \"NODE_ENV=test\" && mocha --timeout 15000 server/**/*.test.js",
  "test-watch": "nodemon --exec 'npm test'"
   }

      

this error is due to mocha.

+2


source


You can simply add the timeout to a specific test to increase / override the default timeout, which is 2 seconds. I had the same problem, but I was able to work around it using:

it('Test', (done) => { 
//your code  
done();
}).timeout(10000);

      

+1


source


The idea is to increase the waiting time.
An alternative way is to do it in only the required way:

 it('remove existing subdocument', function(done) {
         this.timeout(10000);
      //your code is here
      done();
    });

      

This will help me solve the problem.

0


source







All Articles