使用 mocha 测试 asyc/await 时使用 done() 的正确方法

Correct way to use done() while testing asyc/await with mocha

我正在用 mocha 练习基本单元测试用例,有点困惑 HOWWHEN 使用 done()处理程序。

  1. 如何使用done()?

下面是我无法使用的示例代码 done:

it('Testing insertDocumentWithIndex', async (done) => {
  try{
    var data = await db.insertDocumentWithIndex('inspections', {
      "inspectorId" : 1,
      "curStatus" : 1,
      "lastUpdatedTS" : 1535222623216,
      "entryTS" : 1535222623216,
      "venueTypeId" : 1,
      "location" : [
        45.5891279,
        -45.0446183
      ]
    })
    expect(data.result.n).to.equal(1);
    expect(data.result.ok).to.equal(1);
  }
  catch(e){
    logger.error(e);
    done(e);
  }
})

当我运行时,它失败并抛出错误-

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

但是 done 应该只在失败的情况下调用(如果我遗漏了什么,请纠正我,我是初学者),我在 catch 块中完成并来到返回 Promise 的第二点,效果很好。见下面代码

it('Testing insertDocumentWithIndex', async () => {
  return new Promise(async (resolve, reject) => {
    try{
      var data = await db.insertDocumentWithIndex('inspections', {
        "inspectorId" : 1,
        "curStatus" : 1,
        "lastUpdatedTS" : 1535222623216,
        "entryTS" : 1535222623216,
        "venueTypeId" : 1,
        "location" : [
          45.5891279,
          -45.0446183
        ]
      })
      expect(data.result.n).to.equal(1);
      expect(data.result.ok).to.equal(1);
      resolve()
    }
    catch(e){
      reject(e);
    }
  })
});

但这需要一个额外的 Promise 构造代码,它是反模式的。但它提出了另一个问题

  1. 什么时候应该使用done

任何有关使用 mocha 编写测试用例的更好方法的帮助或建议都会有所帮助。

正确的方法是不要将 doneasync..await 一起使用。 Mocha 支持 promise 并且能够链接从 it 等函数返回的 promise。 async 函数是一个总是 returns 承诺的函数的语法糖:

it('Testing insertDocumentWithIndex', async () => {
    var data = await db.insertDocumentWithIndex('inspections', {
      "inspectorId" : 1,
      "curStatus" : 1,
      "lastUpdatedTS" : 1535222623216,
      "entryTS" : 1535222623216,
      "venueTypeId" : 1,
      "location" : [
        45.5891279,
        -45.0446183
      ]
    })
    expect(data.result.n).to.equal(1);
    expect(data.result.ok).to.equal(1);
})

done 仅用于测试不涉及承诺的异步 API。即便如此,转换为 promise 通常会导致更清晰的控制流。

还有这个

it('Testing insertDocumentWithIndex', async () => {
  return new Promise(async (resolve, reject) => {
  ...

是 promise 构造反模式,由于 async promise 构造函数回调而变得更糟。

这些问题也适用于其他具有类似 API、Jest 和 Jasmine 的 JS 测试框架。