2017-10-12 78 views
1

我試圖瞭解Jest的異步測試。使用setTimeout測試Promise

我的模塊有一個函數,它接受一個布爾值並返回一個值的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 } 

我想測試這個使用玩笑。我想我需要使用模擬定時器玩笑提供,所以我的測試腳本看起來有點像這樣:

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') 
      }) 
    }) 
}) 

我碰到下面的錯誤/失敗測試,​​是否我叫​​

Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL. 

您能否解釋我要出錯的地方,以及我可能做些什麼來獲得通過測試,以便按照預期的方式解決問題?

回答

3

致電jest.useFakeTimers()嘲笑每一個定時器功能,你必須必須控制。而不是自動運行計時器,您可以手動提前。 jest.runTimersToTime(msToRun)函數會提前msToRun毫秒。這是很常見的,你想快速前進,直到每個計時器已經過去,並且計算所有計時器完成所需的時間會很麻煩,所以Jest提供了jest.runAllTimers(),這表明已經有足夠的時間過去了。

在測試的問題是,你永遠不會調用​​的測試,但你怎麼稱呼它在afterAll鉤,這就是所謂後的測試已經完成。在測試期間,計時器保持爲零,因此實際上不會調用回調函數,Jest會在預定義的時間間隔(默認值:5秒)後中止它以防止被潛在的無盡測試卡住。只有在測試超時後,您才能撥打​​,此時它不會執行任何操作,因爲所有測試都已完成。

你需要做的是啓動承諾,然後提前計時器。

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 
    }) 
}) 
+0

This Works!非常感謝解釋和解釋和代碼示例。 –