1
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?

JestとReact Testing Libraryで遭遇した「received value must be an HTMLElement」エラーの解決法(waitForとfindByの違い)

Posted at

はじめに

React Testing LibraryとJestを使ってテストコードを書いていたところ、toBeInTheDocument() に関するエラーにつまずいたので、備忘録も兼ねて記事にまとめておきます。

問題

テストを実行したところ、以下のエラーが出ました。

    received value must be an HTMLElement or an SVGElement.
    Received has type:  object
    Received has value: {}

これは、toBeInTheDocument() に渡された値が HTMLElement ではなく、空のオブジェクト {} になっているため発生するエラーです。

該当のテストコード

describe("未入力テスト", () => {
  it("入力をしないで登録を押すとエラーが表示されること", async () => {
    render(<App />);

    //useEventをセットアップ
    const user = userEvent.setup();

    await waitFor(() => {
      expect(screen.queryByText("ロード中")).not.toBeInTheDocument();
    });

    //学習内容入力
    await user.clear(screen.getByTestId("studyContent"));

    //学習時間入力
    await user.clear(screen.getByTestId("studyTime"));

    //登録ボタン押下
    const registerButton = screen.getByRole("button", { name: "登録" });
    await user.click(registerButton);

    await waitFor(() => {
      const error = screen.findByTestId("errorMessage");
      expect(error).toBeInTheDocument();
    });
  });
});

原因

findByは非同期で要素を探すメソッドで、内部で自動的に待機処理(waitFor)を含んでいます。そのため、さらに外側で waitFor を使うと、非推奨な重ねがけになり、正しく処理できないため、エラーが発生していました。

解決方法

findByTestId を使わず、代わりに getByTestId を waitFor の中で使用することで解決しました。

修正コード

    await waitFor(() => {
      const error = screen.getByTestId("errorMessage");
      expect(error).toBeInTheDocument();
    });

findByとwaitForの基本と使い分け

findByとwaitForの違いと使い分けをまとめました。

findBy~ は非同期処理のメソッドで、要素が見つかるまで自動的に待機します。内部的には waitForgetBy~ を組み合わせたものです。デフォルトでは最大1000msまで待機し、その時間内に要素が見つからない場合はエラーになります。特定の1つの要素を探すときに使います。

waitFor はコールバック関数内のアサーションが成功するまで待機する汎用的な関数です。複数のアサーションや、より複雑な条件を確認する場合に適しています。

使い分け

  • findBy~ を使うべき場合:

    • 単一の要素が非同期で表示されるのを待つ必要がある場合
    • シンプルに「要素が表示されるまで待つ」だけの場合
  • waitFor を使うべき場合:

    • 複数の条件や複雑なアサーションを待つ必要がある場合
    • 特定の状態が発生するまで待つ必要がある場合

おわりに

どちらも非同期処理で使われるため、最初は使い分けに戸惑いましたが、今回のエラーを通してそれぞれの役割の違いを理解することができました。

参考

1
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
1
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?