web-dev-qa-db-ja.com

mochaでasync / awaitをテストするときにdone()を使用する正しい方法

私はmochaで基本的な単体テストケースを練習していて、少し混乱しています[〜#〜] how [〜#〜][〜#〜] when [〜#〜]to use 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);
  }
})

実行すると失敗してエラーが発生します-

エラー:2000msのタイムアウトを超えました。非同期テストとフックの場合は、「done()」が呼び出されていることを確認してください。 Promiseを返す場合は、それが解決されることを確認してください。

しかし、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を使用してテストケースを作成するためのより良いアプローチに関するヘルプや提案があれば役立ちます。

6

正しい方法は、doneasync..awaitと一緒に使用しないことです。 Mochaはpromiseをサポートし、itなどの関数から返されるpromiseをチェーンすることができます。そして、async関数は、常にpromiseを返す関数の構文糖衣です。

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は、promiseを含まないのではなく、非同期APIのテストにのみ必要です。それでも、promiseに変換すると、制御フローがよりクリーンになることがよくあります。

この

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

これは、promiseコンストラクタのアンチパターンです。これはasyncpromiseコンストラクタのコールバックのためにさらに悪化します。

4
Estus Flask