[英]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將等待它完成而無需任何額外的設置。 另外,你可以使用async
和await
來使它更好,因為它是承諾之上的語法糖。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.