VitestでsetTimeoutを含むコードのテストを書く

2024/08/13に公開

なにこれ

Vitestでの非同期処理に苦しんでいる人向け。

結論

テストする処理

const someValue = ref(false);
const doSomething = () => {
  setTimeout(() => {
    someValue.value = true;
  }, 500);
};

testコード

describe('test with setTimeout!', () => {
  test('doSomething', () => {
    vi.useFakeTimers({
      shouldAdvanceTime: true,
    }); // #1

    doSomething();
    vi.advanceTimersByTime(500); // #2
    expect(someValue.value).toBeTruthy();

    vi.useRealTimers(); // #3
  });
});

解説

  1. vi.useFakeTimersでtimerをmockする[1]
  2. vi.advanceTimersByTimeでtimerの時間を進める
  3. (後処理)vi.useRealTimersでtimerのmockを解除

補記

まとめ

動くと見せかけて動かないパターン、まれによくある。

それではまた次回。

脚注
  1. 実際はvi.useFakeTimerbeforeEachに、vi.useRealTimersafterEachに配置するような使い方が多くなりそうです ↩︎

  2. 現時点での暫定対応 ↩︎

SMARTCAMP Engineer Blog

Discussion