1
0

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 Hook Form + Testing Library で「Unable to find an element with the text: …」が出るときの対処法

Posted at

はじめに

フォームの必須チェックを React Hook Form + Chakra UI で実装し、Testing Library(Jest) でテストしたら、UIでは見えているエラーメッセージがテストでは見つからない——そんな経験、ありませんか?
この現象の多くは「非同期描画」と「テキストの一致条件」が原因です。ここでは、同じハマりを避けるための汎用的な原因と解決策を、最小コードとテスト例でシンプルにまとめます。

問題

テストが落ちる:

Unable to find an element with the text: IDは必須です

落ちるテスト例:

すぐにDOMを探してしまう

expect(screen.getByText("IDは必須です")).toBeInTheDocument();

なぜ起きる?(普遍的な原因)

  • 非同期描画
    React Hook Form のバリデーションは submit/blur 後に state が更新 → DOM に反映される。クリック直後はまだ表示されない。

  • 条件付きレンダリング
    Chakra UIの<FormErrorMessage>はエラー時だけ描画。エラーが無ければ DOM に存在しない。

  • テキスト一致の厳しさ
    完全一致だと<p>などのラップや微妙な文言差で拾えないことがある。

解決方法(まずはこれで安定)

  1. 非同期待機:findBy/ waitFor を使う
    要素が現れるまで待つ
expect(await screen.findByText(/IDは必須です/i)).toBeInTheDocument();

もしくは

await waitFor(() => {
  expect(screen.getByText(/IDは必須です/i)).toBeInTheDocument();
});

2.テキストは柔らかくマッチ

正規表現(/…/i)で大文字小文字や微妙な差に強くする

UIとテストで文言を統一(「必須です」 vs 「IDは必須です」などのズレをなくす)

3.できれば userEvent を使う

実際のユーザー操作に近いイベント(type, click, tab, clear など)を発火することで、blur/change 等が自然に起き、再現性が高いテストになる。

const user = userEvent.setup();
await user.type(screen.getByLabelText(/ID/i), "");
await user.click(screen.getByRole("button", { name: /登録/i }));
expect(await screen.findByText(/IDは必須です/i)).toBeInTheDocument();

コード全体(最小例)

コンポーネント

<FormControl isInvalid={!!errors.userId}>
  <FormLabel>ID</FormLabel>
  <Input {...register("userId", { required: "IDは必須です" })} />
  <FormErrorMessage>{errors.userId?.message}</FormErrorMessage>
</FormControl>

テスト

test("ID未入力でエラー表示", async () => {
  render(<SampleForm />);
  const user = userEvent.setup();
  await user.click(screen.getByRole("button", { name: /登録/i }));

  expect(await screen.findByText(/IDは必須です/)).toBeInTheDocument();
});

まとめ

  • 「UIでは見えるのにテストで取れない」= 非同期描画が原因

  • findByText / waitFor を使い、DOMに現れるまで待つ

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?