VitestでTimerのMock
timerのmockを有効化する
code:javascript
import { vi } from 'vitest';
vi.useFakeTimers();
// ここから、タイマー関連の関数はモックされる
めちゃくちゃ雑に言えば、無限秒進めるってこと?mrsekut.icon
無限に続く場合は、10,000回実行後にthrowするともある
非公式な用語っぽい(?)が
GPT-4.icon
システム時刻の設定
モックされたタイマー環境下で、システムの現在時刻を特定の日時に設定するには、vi.setSystemTime()を使用します。これにより、Date.now()やnew Date()で取得される時刻を制御できます。
code:javascript
const mockDate = new Date(2025, 0, 29, 12, 0, 0); // 2025年1月29日12時00分00秒
vi.setSystemTime(mockDate);
console.log(new Date()); // 出力: 2025-01-29T03:00:00.000Z (タイムゾーンに依存)
タイマーの進行
モックされたタイマーを特定の時間だけ進めるには、vi.advanceTimersByTime()を使用します。これにより、指定した時間だけタイマーが進行し、対応するコールバックが実行されます。
code:javascript
const callback = vi.fn();
setTimeout(callback, 1000); // 1秒後に実行されるコールバック
vi.advanceTimersByTime(1000); // タイマーを1秒進める
expect(callback).toHaveBeenCalledTimes(1); // コールバックが1回呼ばれたことを確認
タイマーのリセット
スケジュールされている全てのタイマーをクリアするには、vi.clearAllTimers()を使用します。これにより、未実行のタイマーは全て削除されます。
code:javascript
setTimeout(() => {
// このコードは実行されません
}, 5000);
vi.clearAllTimers(); // 全てのタイマーをクリア
タイマーのモックを無効化する
テスト終了後、タイマーのモックを元の実装に戻すには、vi.useRealTimers()を呼び出します。これにより、タイマー関連の関数が実際の動作に戻ります。
code:javascript
vi.useRealTimers();
// ここから、タイマー関連の関数は実際の動作に戻ります
使用例
以下に、営業時間内外での購入処理をテストする例を示します。
code:javascript
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
const businessHours = 9, 17; function purchase() {
const currentHour = new Date().getHours();
if (currentHour > open && currentHour < close) {
return { message: 'Success' };
}
return { message: 'Error' };
}
describe('購入フローのテスト', () => {
beforeEach(() => {
vi.useFakeTimers();
});
afterEach(() => {
vi.useRealTimers();
});
it('営業時間内の購入を許可する', () => {
const date = new Date(2025, 0, 29, 13); // 13時(営業時間内)
vi.setSystemTime(date);
expect(purchase()).toEqual({ message: 'Success' });
});
it('営業時間外の購入を拒否する', () => {
const date = new Date(2025, 0, 29, 19); // 19時(営業時間外)
vi.setSystemTime(date);
expect(purchase()).toEqual({ message: 'Error' });
});
});
この例では、vi.useFakeTimers()でタイマーのモックを有効化し、vi.setSystemTime()でシステム時刻を設定しています。テスト終了後にはvi.useRealTimers()で元のタイマーに戻しています。
名前だけで判断してるので見つけたらちゃんと直す
vi.advanceTimersByTime
vi.advanceTimersToNextTimer
vi.getTimerCount
vi.clearAllTimers
vi.dynamicImportSettled
vi.getRealSystemTime
vi.hoisted
vi.importActual
vi.resetAllMocks
vi.resetConfig
vi.resetModules
vi.restoreAllMocks
vi.restoreCurrentDate
vi.runAllTicks
vi.runAllTimers
vi.runOnlyPendingTimers
vi.setSystemTime
vi.setConfig
vi.useRealTimers