Dynamically-generated Mocha tests not executing in async/await context

Viewed 953

I am unable to get my Mocha tests to run. Part of what I need to test against I fetch in an asynchronous manner (from remote server), returned by my getStatus() function (replaced by a timeout for simplicity). I have a similar code sample without async/await which works fine (can provide a repl.it as well if needed).

Simplified code (you can play with it here on repl.it):

const sleep = require('util').promisify(setTimeout);

const getStatus = async function() {
    await sleep(1000);
    return 2;
};

describe('main describe', async function () {
    let uids = [1,2,3];

    describe('Tha test!', async function () {
        console.info('started describe() block...');

        let outcome;
        let status;

        const callback = function () {
            console.info(`inside callback, status is ${status} and outcome is ${outcome}`);
            expect(status).to.equal(outcome);
        };

        for(let uid in uids) {
            status = await getStatus(uids[uid]);
            console.info('the status returned by getStatus is:', status);
            it(`The status for ${uids[uid]} should be ${outcome}`, callback);
        }
    });
});

Note: the callback inside the it() clause was inspired by this question.

Output:

started describe() block...

  0 passing (0ms)

the status returned by getStatus is: 2
the status returned by getStatus is: 2
the status returned by getStatus is: 2

Expected output:

started describe() block...

the status returned by getStatus is: 2
the status returned by getStatus is: 2
the status returned by getStatus is: 2

      1) number 0 should equal 2
      2) number 1 should equal 2
      ✓ number 2 should equal 2

  1 passing (11ms)
  2 failing

Question: why are my it() clauses not executing?

1 Answers

Turns out you cannot pass an async callback into a describe(). Who knew.

So here's how it should be done in order for all the async stuff to work:

describe('do not put async before the function keyword!', function () {
    uids = process.env.ENV_OBJECTS.split(',');

    let outcome;

    for(let uid in uids) {
        it('Can safely put async before the function here', async function() {
            outcome = await getOutcome(uid);
            // etc.
        });
    }
});
Related