3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

React Testing Library の非同期処理テストで沼った  【act() 、waitFor()】

Last updated at Posted at 2025-03-02

はじめに

React のテストライブラリでは act()waitFor() を使って非同期処理を適切に待つ必要があり、これが原因で何度もテストが通らないことがあります。備忘録として記事にまとめました。

テストの目的

  • ユーザーがフォームに入力し、ボタンを押すと、学習記録のリストが 1 つ増えることを確認する
  • data-testid="record-item" を持つ要素の数をカウントし、登録後に増えていることを期待する
// 初期のリスト数を取得
const initialRecords = (await screen.findAllByTestId("record-item")).length;

// フォーム入力 & 登録ボタンをクリック
await userEvent.type(screen.getByPlaceholderText("テキストを入力"), "React Testing");
await userEvent.type(screen.getByPlaceholderText("0"), "2");
await userEvent.click(screen.getByRole("button", { name: "登録" }));

// 追加後のリスト数をチェック
await waitFor(async () => {
  const newRecords = (await screen.findAllByTestId("record-item")).length;
  expect(newRecords).toBeGreaterThan(initialRecords);
});

発生したエラー

React Testing Library を使ってフォーム入力と登録ボタンの動作をテストしようとしたが、テストが record-item を取得できずに失敗

エラーの原因

データの取得が完了する前にテストが進行してしまっていたことが原因。具体的には、

  1. データ取得が完了する前に record-item を取得しようとしていた
    → API からデータが返るのを待つ前に findAllByTestId("record-item") を呼んでしまい、0 件のまま expect(newRecords).toBeGreaterThan(initialRecords); が失敗

  2. act() で状態更新を待っていなかった
    → ボタンを押した後の画面の更新を待たずに次の処理が走ってしまい、テストが成功しない

修正

act() でユーザー操作をラップ

修正前

await userEvent.click(screen.getByRole("button", { name: "登録" }));

修正後

await act(async () => {
  await userEvent.click(screen.getByRole("button", { name: "登録" }));
});

act() を使うことで、React の状態更新を適切に処理できるように

waitFor()record-item の取得を待つ

修正前

const newRecords = (await screen.findAllByTestId("record-item")).length;

修正後

await waitFor(async () => {
  const newRecords = (await screen.findAllByTestId("record-item")).length;
  expect(newRecords).toBeGreaterThan(initialRecords);
});

waitFor() を使うことで、データ取得が完了するまでテストが進まないようにする

まとめ

  • 非同期処理を伴う UI の変化は act() でラップする
  • API からのデータ取得を待つときは waitFor() を使う
  • エラーが出たら console.log() でデータの流れを確認すると原因が見つかりやすい

React Testing Library で非同期テストを書くときは、act()waitFor() を適切に使うことが重要

この方の記事もとても参考になりました
https://oisham.hatenablog.com/entry/2024/01/18/150850

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?