🔍

React Testing Library で Material UI の TextField を取得する方法

2021/06/10に公開

はじめに

@testing-library/react で Material UI の TextField を取得する際、 label が設定されていても getByRolegetByLabelText で取得したときに label が正しく取得できません。

調べると inputProps を使って data-test-id を使う方法も出てきますが、テストのために data-test-id を指定するのは極力避けたく、他の方法を調査していました。

結論

  • label を設定する
  • 一見不要でも id を設定する
  • getByRole または getByLabelText で取得する
    • 一般的には getByRole が推奨されていますが type="password の場合は使えません

解説

Material UI の TextField コンポーネントを以下のように配置した場合

<TextField id="email" name="email" label="メールアドレス" />

実際には以下の DOM として展開されます。

<div class="MuiFormControl-root MuiTextField-root">
  <label
    class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated"
    data-shrink="false"
    for="email"
    id="email-label"
  >
    メールアドレス
  </label>
  <div class="MuiInputBase-root MuiInput-root MuiInput-underline MuiInputBase-formControl MuiInput-formControl">
    <input
      aria-invalid="false"
      class="MuiInputBase-input MuiInput-input"
      id="email"
      name="email"
      type="text"
      value=""
    />
  </div>
</div>

id="email" を消すと以下のようになります。

<div class="MuiFormControl-root MuiTextField-root">
  <label
    class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated"
    data-shrink="false"
  >
    メールアドレス
  </label>
  <div class="MuiInputBase-root MuiInput-root MuiInput-underline MuiInputBase-formControl MuiInput-formControl">
    <input
      aria-invalid="false"
      class="MuiInputBase-input MuiInput-input"
      name="email"
      type="text"
      value=""
    />
  </div>
</div>

ここで注目したいのは <label>for="email" という箇所です。

<label> タグには for<input>id を指定してあげるとその <input> に関連づけられるという仕様があります。
https://developer.mozilla.org/ja/docs/Web/HTML/Element/label

Material UI の TextField の場合、 id を設定すると for を指定してくれるようです。
よく見たらドキュメントの隅のほうに書いてありました。

If you are using the TextField component, you just have to provide a unique id.

https://material-ui.com/components/text-fields/#accessibility

TextField を使う場合、一見不要でも id をつけるのは癖にしたほうがよさそうです。

余談

@testing-library/react は最初はとっつきづらくて enzyme 使いたい〜〜となってしまいますが、慣れてくるとブラウザ上で操作するように直感的にテストが書けるなと感じてきました。

以下の記事にベストプラクティスが沢山まとめられているので、 @testing-library/react を使用している方は一読してみるとよさそうです。

https://kentcdodds.com/blog/common-mistakes-with-react-testing-library

Discussion