异步回调中的Mocha测试

时间:2018-08-15 13:08:23

标签: node.js async-await mocha

我已经简化了示例,以便能够很好地解释它。我有一个要迭代的数组。对于数组的每个元素,我想使用async / await函数执行测试,因此我有以下代码:

const chai = require('chai');
const expect = chai.expect;

describe('Each film', async() => {

  await Promise.all([1, 2, 3].map(async(n) => {
    await new Promise(resolve => setTimeout(() => resolve(), 1000));
    console.log('N:', n);

    it('test', async() => {
      expect(true).to.be.true;
    });
  }));

});

执行此操作将产生以下输出:

  0 passing (1ms)

N: 1
N: 2
N: 3

但是,如果我不使用异步/等待,它将按照我的期望执行,因此它将生成三个可以正确解决的测试。

这里会发生什么?

更新

我终于发现setTimeout可用于异步加载数据,然后动态生成测试。这是来自摩卡页面的解释:

  

如果在运行任何套件之前需要执行异步操作,则可以延迟根套件。使用--delay标志运行摩卡咖啡。这会将特殊的回调函数run()附加到全局上下文:

所以我最终以这种方式编写了代码:

const chai = require('chai');
const expect = chai.expect;

setTimeout(async() => {
  await Promise.all([1, 2, 3].map(async(n) => {

    describe(`Element number ${n}`, () => {

      it('test', async() => {
        await new Promise(resolve => setTimeout(() => resolve(), 1000));
        expect(true).to.be.true;
      });

    });

  }));

  run();
}, 500);

产生以下输出:

➜ node_modules/.bin/mocha --delay test.js                                           


  Element number 1
    ✓ test (1005ms)

  Element number 2
    ✓ test (1001ms)

  Element number 3
    ✓ test (1002ms)


  3 passing (3s)

1 个答案:

答案 0 :(得分:1)

Mocha不支持异步describe函数。您可以 动态生成测试,如here所述,但是生成必须仍然是同步的。

任何未同步创建的测试都不会被跑步者接受。因此,输出顶部的0 passing行。 Mocha决定在您的诺言兑现之前还没有任何测试。

这并不是说不可能测试您的产品,只是您需要重新考虑如何使用Mocha对其进行测试。例如,以下内容类似于预先加载所有内容并在各种测试中对每个内容进行断言:

const chai = require('chai');
const expect = chai.expect;

describe('Each item', () => {
    let items;

    before(async () => {
        items = [];
        await Promise.all([1, 2, 3].map(async(n) => {
            await new Promise(resolve => setTimeout(() => resolve(), 1000));
            items.push(n);
        }));
    })

    it('is a number', () => {
        for (item of items) {
            expect(item).to.be.a('number');
        }
    });

    it('is an integer', () => {
        for (item of items) {
            expect(item % 1).to.equal(0)
        }
    });

    it('is between 1 and 3', () => {
        for (item of items) {
            expect(item).to.be.within(1, 3)
        }
    });
});

不幸的是,您将无法在每个项目的输出中显示完全独立的测试。如果需要,您可以签出另一个测试运行程序。我真的没有与其他人的足够经验来说他们中的任何一个是否支持这一点。但是,如果他们这样做,我会感到惊讶,因为这很不寻常。