2017-10-12 17 views
1

Jestの非同期テストを理解しようとしています。JestとsetTimeoutを使って約束をテストする

私のモジュールはブール値を受け取り、値の約束を返す関数を持っています。 executer関数は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を使ってテストしたいと思います。私は私のテストスクリプトは、ビットのようになりますので、冗談が提供するモックタイマーを使用する必要があることを推測:

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

これは機能します。説明と説明とコードサンプルに感謝します。 –

関連する問題