# Material-UIのレンダリングを確認するテストコードを書いてみた


 この記事では、私がはじめてreactのテストコードを書いた時に、詰まってしまった問題と、それを解決するためにとった対策について紹介しています。
 

詰まってしまった問題

 react-testing-libraryの.getByRole()メソッドを使ってtype="password"の要素を取得しようとしたときに、テストコードのある部分でエラーになってしまいました。

解決するためにとった対策

単純ですが、.getByRole()以外のメソッドを使用することで、対象の要素を取得することができました。 

この記事で前提としている環境

この記事は以下の環境を前提に書かれています。

(1)material-uiをインストールしている。
(2)react-testing-library と Jest をインストールしている
   ※(2)は、npx create-react-app を実行するとデフォルトでインストールされます。
(3)TypeScriptでコードが書かれている

とりあえずテストコードを書いてみた

 ログイン画面を作ろうとして、以下のとおり、Material-UIを活用して、メールアドレスとパスワードの入力するコンポーネントを作りました。

Auth.tsx

const Auth: React.FC = () => {
  const classes = useStyles();
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");

return (
    <>
      <FormControl className={classes.textField} variant="outlined">
        <InputLabel htmlFor="email">メールアドレス</InputLabel>
        <OutlinedInput
          className={classes.textField}
          value={email}
          onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
            setEmail(e.target.value);
          }}
          labelWidth={100}
        />
      </FormControl>
      <FormControl className={classes.textField} variant="outlined">
        <InputLabel htmlFor="password">パスワード</InputLabel>
        <OutlinedInput
          className={classes.textField}
          type="password"
          value={password}
          onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
            setPassword(e.target.value);
          }}
          labelWidth={80}
        />
      </FormControl>
    </>
  );

※解説に必要な箇所に絞って、ものすごく簡略化して書いています。

このコンポーネントに対し、以下のとおりテストコードを書きました。

Auth.test.tsx
import React from "react";
import { render, screen } from "@testing-library/react";
import Auth from "./Auth";

describe("Rendering", () => {
  it("Should render the elements correctly", () => {
    render(<Auth />);
    expect(screen.getAllByRole("textbox")[0]).toBeTruthy();
    expect(screen.getByRole("textbox"))[1].toBeTruthy();
  });
});

 すると、以下の画像のように、type="password"のinput要素を取得しようとした際にエラーが発生してしまいました。

.getByRole()では、type= "password"の要素を取得することができない

以下のサイトで.getByRoleで選択できるロールの一覧を確認してみたところ、.getByRole()では、type= "password"の要素を取得することができないことがわかりました。 
 https://github.com/A11yance/aria-query

.getByTestIdを試してみる

 React-Testing-Libraryを使って、コンポーネントの要素がきちんとレンダリングされているか
確認するためには、さまざまな方法がありますが、今回はgetByTestIdを使用する方法を試してみました。

① レンダリングの確認対象とする要素にdata-testid=""というプロパティをつける

 ※id=""という形ではない点に注意です!

Auth.tsx

const Auth: React.FC = () => {
  const classes = useStyles();
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");

return (
    <>
      <FormControl className={classes.textField} variant="outlined">
        <InputLabel htmlFor="email">メールアドレス</InputLabel>
        <OutlinedInput
          data-testid="email"
          className={classes.textField}
          value={email}
          onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
            setEmail(e.target.value);
          }}
          labelWidth={100}
        />
      </FormControl>
      <FormControl className={classes.textField} variant="outlined">
        <InputLabel htmlFor="password">パスワード</InputLabel>
        <OutlinedInput
          data-testid="password"
          className={classes.textField}
          type="password"
          value={password}
          onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
            setPassword(e.target.value);
          }}
          labelWidth={80}
        />
      </FormControl>
    </>
  );

.getByTestId("")を要素の選択条件としてテストコードを書く

Auth.test.tsx
import React from "react";
import { render, screen } from "@testing-library/react";
import Auth from "./Auth";

describe("Rendering", () => {
  it("Should render the elements correctly", () => {
    render(<Auth />);
     expect(screen.getByTestId("email")).toBeTruthy();
     expect(screen.getByTestId("password")).toBeTruthy();
  });
});

みたいな感じで。

他にもgetByRoleや getAllByrole、getByLabelTextなど、要素を選択するさまざまな条件があるので、いろいろ試してみると勉強になります。

その他

 Auth.tsxやFeed.tsxみたいに、tsxファイルで作ったコンポーネントのテストコードは
必ずtsxファイルで書かないと、テストを実行したときエラーになるので、注意です!
自分はこのエラーで3日間ハマってしまいました ^^;

参考

Udemyの教材 Reactソフトウェアテスト(Hooks+ReduxToolKit時代のモダンテスト手法)
https://www.udemy.com/course/reacthooksreduxtoolkit/

getByクエリの概要
https://testing-library.com/docs/queries/about

getByRole で選択できるロール一覧
 https://github.com/A11yance/aria-query