簡體   English   中英

異步功能的表現與我對Jest的預期不同

[英]Async function not behaving as I expect with Jest

Javascript Jest測試框架文檔說我需要在我的回調中添加done()來測試異步函數,否則函數將在測試完成后返回,因此測試將失敗。 我已將Jest添加到我的package.json,以及以下兩個文件:

src.js:

function fetchData(cb) {
  setTimeout(cb, 2000, 'peanut butter')
}

module.exports = fetchData

src.test.js:

const fetchData = require('./src')

test('the data is peanut butter', () => {
  function callback(data) {
    expect(data).toBe('peanut butter')
    // no done() method!
  }

  fetchData(callback);
})

我通過上面的代碼傳遞測試,但我認為我應該得到一個失敗的測試,因為我沒有在我的測試文件中done() 我的fetchData()方法不是異步的嗎?


編輯:按照尼古拉斯的回答,我將代碼更改為:

src.js:

function fetchData(cb) {
  setTimeout(cb, 2000, 'peanut')
}

module.exports = fetchData

src.test.js:

const fetchData = require('./src')

test('the data is peanut butter', () => {
  function callback(data) {
    expect(data).toBe('peanut butter')
    done()
  }

  fetchData(callback);
})

測試運行者應根據Jest文檔評估期望/斷言並且失敗( 花生通過, 花生醬預期),但仍顯示通過測試。

此外,Jest文檔說:

If done() is never called, the test will fail, which is what you want to happen

測試在回調中使用和不使用done()方法傳遞,並且有和沒有正確的( peanut butter )參數都傳遞給回調(即所有四個變量都通過)。

如果你沒有將done作為參數傳遞,那么測試運行器會認為代碼是同步的,並且不會等待發生特殊情況 - 在這種情況下調用done

因此, 您的斷言/期望有機會運行之前 ,測試會被標記為成功。

你的fetchData是異步的,Jest對它沒有影響。 另一方面,Jest需要知道測試何時結束,這通常是測試函數退出時,但只包括同步代碼。 在你的情況下,當你的測試函數退出時,你沒有調用任何斷言,Jest認為這是成功的(因為沒有失敗)。

為了證明沒有調用斷言,我將使用expect.assertions(number)僅傳遞測試,如果它調用完全number斷言。 例如,如果在示例中將其設置為1:

test('the data is peanut butter', () => {
  // Require exactly 1 assertion to pass the test
  expect.assertions(1)

  function callback(data) {
    expect(data).toBe('peanut butter')
  }

  fetchData(callback)
})

您將看到錯誤消息:

● the data is peanut butter

  expect.assertions(1)

  Expected one assertion to be called but received zero assertion calls.

如您所見,沒有調用斷言。 除了演示目的之外,您還可以使用expect.assertions來確保在未調用斷言時測試失敗。

對於任何異步任務,您需要讓Jest知道測試是異步的,您需要在完成時通知Jest。 一種方法是done回調。 當您的測試函數采用一個參數(通常稱為done )時,Jest會將其視為異步測試並等待您調用done()回調,或達到超時閾值(默認值:5s)。 在您編輯的示例中,您的函數接受零參數,而您對done()的調用不是Jest的回調。

test('done callback', done => {
  //                  ^^^^ 1 argument
  // Jest waits until this callback is called or the timeout was reached.
  // ...
})

test('no callback argument', () => {
  //                         ^^ no argument
  // Test finishes as soon as the function exits
  // ...
})

這很少被使用,因為承諾現在更常見,它們使這更簡單,因為你可以返回承諾,Jest將等待它完成而無需任何額外的設置。 另外,你可以使用asyncawait來使它更好,因為它是承諾之上的語法糖。

另請參閱測試異步代碼 - 承諾測試異步代碼 - 異步/等待

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM