Jestテスト|Jestで非同期処理のテストをする

非同期処理の場合のテストコードの書き方を学ぶ

5/28/2025

非同期処理のテスト

API通信、タイマー処理などを含む関数を正しく検証するには、Promiseの完了を待つ・コールバックが呼ばれたことを確認するなど、同期的なテストとは異なる配慮が必要となってくる。

特に配慮せずテストコードを書くと、Jestテストでは非同期処理が完了するのを待たずにテストが終わってしまうことがある。

非同期処理Promise|成功パターン

🔸テスト対象のサンプルコード|asyncFunction.ts

下記関数waitAndReturn()は、1秒後に 完了しました という文字列を返す。
Promiseは成功するとresolveを返す。

export const waitAndReturn = (): Promise<string> => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('完了しました');
    }, 1000);
  });
};

🔸テストコード|asyncFunction.test.ts

import { waitAndReturn } from './asyncFunction';

test('waitAndReturnは「完了しました」を返す', async () => {
  const result = await waitAndReturn(); // 非同期処理が終わるのを待つ
  expect(result).toBe('完了しました');
});

test 関数のコールバックに async を付け、関数の呼び出しに await を使い非同期処理が終わるのを待つ。
そして最後にexpect で結果を確認。


非同期処理Promise|失敗パターン

🔸テスト対象のサンプルコード|rejectFunction.ts

関数willFail()は、1秒後に エラーです という文字列を返す。
Promiseは失敗するとrejectを返す。

export const willFail = (): Promise<string> => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject('エラーです');
    }, 1000);
  });
};

🔸テストコード|rejectFunction.test.ts

import { willFail } from './rejectFunction';

test('willFailはエラーを返す', async () => {
  await expect(willFail()).rejects.toBe('エラーです');
});

上記の expect(...).rejects.toBe(...) は、Promise がエラーになる(rejectされる)ことを期待する書き方。


タイマーを使った関数とテスト(基本)

🔸テスト対象のサンプルコード|timeoutCallback.ts

関数callAfterDelayは1秒後に callback();のコールバック関数を呼び出す。

export const callAfterDelay = (callback: () => void) => {
  setTimeout(() => {
    callback();
  }, 1000);
};

📝(callback: () => void) の書き方について

「callback」は引数(コールバック関数)の名前。「: () => void」はこの引数が「引数なし・戻り値なしの関数」であるという型の指定
分解すると…

type CallbackFunction = () => void;

export const callAfterDelay = (callback: CallbackFunction) => {
  // ...
};

🔸テストコード|timeoutCallback.test.ts

done()を使用する。done()は非同期処理が終わったことをJestに知らせるための関数。
これを呼び忘れるとテストがタイムアウトする。

import { callAfterDelay } from './timeoutCallback';

test('1秒後にコールバックが呼ばれる', (done) => {
  callAfterDelay(() => {
    expect(true).toBe(true); // とりあえず確認用
    done(); // テスト完了をJestに通知
  });
});

done() の役割:

test() の中は 同期的 or async/await を使う場合、Jestが自動でテスト完了を検知できる。
しかし、コールバック関数を使って非同期処理する場合、Jestはテストが「まだ終わっていない」と分からない。そのため、Jestに「今終わりました!」と手動で知らせる必要がある。


✅まとめ

🔸非同期処理のテストの特徴

  • async / awaitPromise を直接扱う。
  • 非同期関数の 結果が正しいかどうか(成功 / エラー) をテスト。

🔸タイマーを使ったテストの特徴

  • setTimeoutsetInterval を使った「一定時間後に起きる処理」が対象。
  • コールバックが呼ばれるかどうか を確認する。
  • Jestのタイマー制御APIjest.useFakeTimers() など)を使うと効率的。

種類

主な目的

代表的な書き方例

① 非同期処理のテスト

Promise の 成功 / 失敗 を確認

await, expect(...).resolves / rejects

② タイマーを使ったテスト

時間経過後に何かが実行されるか を確認

setTimeout, jest.useFakeTimers() など