matsev
matsev

Reputation: 33749

Conditionally asynchronously execute mocha test

How can I conditionally execute mocha tests based if the condition is an asynchronous function call?

I have tried to make an asynchronous implementation based on a synchronous example. In both snippets below I expected some test to be executed since the promise returned by asyncCondition() is resolved to true.

First, I tried to await the condition:

const assert = require('assert');

const asyncCondition = async () => Promise.resolve(true);

describe('conditional async test', async () => {
  const condition = await asyncCondition();

  (condition ? it : it.skip)('some test', () => {
    assert.ok(true);
  });    
});

Result: No tests were found.

Next, I tried an asynchronous before hook:

const assert = require('assert');

describe('conditional async test', async () => {
  let condition;

  before(async () => {
    condition = await asyncCondition();
  });

  (condition ? it : it.skip)('some test', () => {
    assert.ok(true);
  });
});

Result: Pending test 'some test'.


The code works if if the line const condition = await asyncCondition() is changed to execute a synchronous function call.

Upvotes: 2

Views: 667

Answers (1)

Brian Adams
Brian Adams

Reputation: 45780

The Mocha run cycle runs all describe callbacks and collects the tests synchronously, so only synchronously available conditions can be used to toggle between it and it.skip during the describe callback execution.

How can I conditionally execute mocha tests based if the condition is an asynchronous function call?

Mocha provides .skip() to...

...tell Mocha to simply ignore these suite(s) and test case(s).

.skip() can be used within a before to skip all tests in a test suite:

const assert = require('assert');

const asyncCondition = async () => Promise.resolve(false);

describe('conditional async test', function () {

  before(async function () {
    const condition = await asyncCondition();
    if (!condition) {
      this.skip();  // <= skips entire describe
    }
  });

  it('some test', function () {
    assert.ok(true);
  });

});

...or it can be used within a single test to skip just that test:

const assert = require('assert');

const asyncCondition = async () => Promise.resolve(false);

describe('conditional async test', function () {

  let condition;
  before(async function () {
    condition = await asyncCondition();
  });

  it('some test', function () {
    if (!condition) this.skip();  // <= skips just this test
    assert.ok(true);
  });

});

Upvotes: 1

Related Questions