本文へスキップ

擬似タイマーの使用

コードでタイマー(`setTimeout`、`setInterval`、`clearTimeout`、`clearInterval`)を使用する場合、テストが予測不可能になり、遅くなったり、不安定になったりする可能性があります。

これらの問題を解決するため、またはコードで特定のタイムスタンプに依存する必要がある場合は、ほとんどのテストフレームワークで、テスト内の実際のタイマーを擬似タイマーに置き換えるオプションを提供しています。これには副作用があります。テストで擬似タイマーを使用すると、テスト内の*すべての*コードが擬似タイマーを使用します。

擬似タイマーを設定する一般的なパターンは、通常、`beforeEach`内で行われます。例:

// Fake timers using Jest
beforeEach(() => {
jest.useFakeTimers()
})

擬似タイマーはネイティブのタイマー関数をモックしているため、通常のモックと同様に、テストの実行後にタイマーを復元する必要があります。これにより、擬似タイマーが他のテストケースや、実際のタイマーが期待されるクリーンアップ関数に漏れるのを防ぎます。

そのため、通常は`afterEach`で`useRealTimers`を呼び出します。

実際のタイマーに切り替える前に`runOnlyPendingTimers`を呼び出すことも重要です。これにより、実際のタイマーに切り替える前に、保留中のすべてのタイマーをフラッシュできます。タイマーを進めてから実際のタイマーに切り替えるだけであれば、スケジュールされたタスクは実行されず、予期しない動作が発生します。これは、あなたが認識していないタスクをスケジュールするサードパーティにとって特に重要です。

Jestを使った例を以下に示します。

// Running all pending timers and switching to real timers using Jest
afterEach(() => {
jest.runOnlyPendingTimers()
jest.useRealTimers()
})
注記

擬似タイマーと`user-event`を組み合わせると、テストのタイムアウトが発生する可能性があります。この問題を防ぐには、`advanceTimers`オプションを参照してください。