[英]Testing a Promise using setTimeout with Jest
我正在嘗試了解Jest的異步測試。
我的模塊有一個函數,它接受一個布爾值並返回一個值的Promise。 執行器函數調用setTimeout
,並且在超時回調中,promise根據最初提供的布爾值來解析或拒絕。 代碼如下所示:
const withPromises = (passes) => new Promise((resolve, reject) => {
const act = () => {
console.log(`in the timout callback, passed ${passes}`)
if(passes) resolve('something')
else reject(new Error('nothing'))
}
console.log('in the promise definition')
setTimeout(act, 50)
})
export default { withPromises }
我想用Jest測試一下。 我想我需要使用Jest提供的模擬計時器,所以我的測試腳本看起來有點像這樣:
import { withPromises } from './request_something'
jest.useFakeTimers()
describe('using a promise and mock timers', () => {
afterAll(() => {
jest.runAllTimers()
})
test('gets a value, if conditions favor', () => {
expect.assertions(1)
return withPromises(true)
.then(resolved => {
expect(resolved).toBe('something')
})
})
})
我得到以下錯誤/失敗的測試,無論我是否調用jest.runAllTimers()
Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
你能解釋一下我出錯的地方以及我可以采取什么措施來獲得通過預期解決的通過測試?
對jest.useFakeTimers()
的調用會使用您必須控制的每個計時器函數進行jest.useFakeTimers()
。 您可以手動前進,而不是自動運行計時器。 jest.runTimersToTime(msToRun)
函數將使msToRun
毫秒提前。 你想要快速前進直到每個計時器都過去是很常見的,計算所有計時器完成所需的時間會很麻煩,所以Jest提供了jest.runAllTimers()
,它假裝已經過了足夠的時間。
測試中的問題是你從不在測試中調用jest.runAllTimers()
,而是在afterAll
鈎子中調用它,在測試結束后調用它。 在測試期間,計時器保持為零,因此您的回調從未被實際調用過,並且Jest在預定義的時間間隔(默認值:5秒)后中止它,以防止陷入潛在的無限測試。 只有在測試超時后,才調用jest.runAllTimers()
,此時它不會執行任何操作,因為所有測試都已完成。
您需要做的是啟動承諾,然后推進計時器。
describe('using a promise and mock timers', () => {
test('gets a value, if conditions favor', () => {
expect.assertions(1)
// Keep a reference to the pending promise.
const pendingPromise = withPromises(true)
.then(resolved => {
expect(resolved).toBe('something')
})
// Activate the timer (pretend the specified time has elapsed).
jest.runAllTimers()
// Return the promise, so Jest waits for its completion and fails the
// test when the promise is rejected.
return pendingPromise
})
})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.