Krimson
Krimson

Reputation: 7664

Promise test timing out even after returning promise

I researched and found out that when testing promises in mocha, you have to return the promise.

I tried to do the following but the test keeps timing out. What the correct way to do this?

describe('A promise', () => {

    it('should not timeout', () => {

        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('hi!');
            }, 3000);
        }).then((msg) => {
            expect(msg).to.equal('hi!');
        });

    });

});

Output:

$ ./node_modules/mocha/bin/mocha test.js


  A promise
    1) should not timeout


  0 passing (2s)
  1 failing

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

Edit: I tried adding the done in the it line and calling it in my then block but it doesn't work

Upvotes: 0

Views: 1132

Answers (4)

Ari Singh
Ari Singh

Reputation: 1296

Try this (only change: ".timeout(5000)" was added to "it"). This works for me. Basically you have to change the default timeout of 2sec for async call - if you expect your async call will take more than 2sec.

describe('A promise', () => {
    it('should not timeout', () => {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('hi!');
            }, 3000);
        }).then((msg) => {
            expect(msg).to.equal('hi!');
        });
    }).timeout(5000);
});

2nd option (no need to change test in this case) :

./node_modules/mocha/bin/mocha --timeout 5000 test-mocha-spec.js

Upvotes: 2

Yurii
Yurii

Reputation: 126

You have 3 options:

  1. return a promise
  2. use done (if you also return promise error will be thrown)
  3. use async/await

In all these cases you have to set timeout threshold, because mocha can't be sure will you resolve your async call or not. It is a protection from endless tests.

Usually, you need to fake you promised calls with some immediately resolved promise with some fake value, so you will not have such problems.

Upvotes: 0

filipbarak
filipbarak

Reputation: 1905

First you need to add the done parameter in the callback

it('should not timeout', (done) => {

and call it at the end,

}).then((msg) => {
    expect(msg).to.equal('hi!');
    done()
});

Upvotes: 0

Striped
Striped

Reputation: 2548

Does this work ?

it('should not timeout', done => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('hi!');
        }, 1000);
    }).then((msg) => {
        expect(msg).to.equal('hi!');
        done();
    });
});

Upvotes: 0

Related Questions