2019」21日目の記事です。フロントエンドエンジニアは数年前に比べ、技術の幅が広がったことにより担当するべき作業も増えてきています。テストもその中の一つです。Testと考えることが多くあります。Library・Jestを使う方法で紹介します。DOMまずはHooksでのDOMのテストです。Reactでのテストではenzymeが有名ですが、今回は使いません。Render時にuseEffectを呼び出すことができません。そのことについてはenzymeのissueでも話し合われています。今回は@testing-library/reactを使用します。Libraryはユーザがコンポーネントを使用するようにテストが設計されreact-dom/test-utilsをラップしたライブラリです。Libraryの方が合っているように感じます。ユニットテストテストを行うために下記のFuga.tsxというコンポーネントを用意しました。Fuga;data-testidはテストをする際に使用するデータ属性です。Libraryのドキュメントではdata-testidは実際のユーザの使用方法とは異なるため、なるべく使用するのは避けるように書かれています。次に実際にテストを書くためにライブラリを追加します。@testing-library/jest-dom@testing-library/jest-domはjestのカスタムマッチャーでDOMテストをより読みやすく簡単に行うことができます。テストコード次に実際にテストを書いていきます。})})getByTestIdで指定しているのが、componentに書いたdata-testid属性です。@testing-library/jest-domを使用しているのでtoHaveTextContent・toHaveStyleなどのカスタムマッチャーで容易にテストすることができます。APIを組み合わせることで、独自のHooksを定義することができるものです。Libraryが出している@testing-library/react-hooksを使います。Hookは普通のJavaScript関数に見えますが、HooksはReactコンポーネントの内部でしか動作することできないので、テストをするためにコンポーネントを書く必要がありますが、そんな煩わしさを解消するテストユーティリティです。Dependenciesとなっているので追加する必要があります。この際使用しているReactのバージョンに合わせる必要があリます。react-test-renderer@^16.12.0テストコードuseInputのユニットテストを書いていきます。})})renderHook関数がCustomHookをモックコンポーネントでラップしてくれます。今回はinput関連のhooksだったため@testing-library/reactと併用し、fireEventでイベントを発火させることでテストをしています。v5.1から対応したフックです。このフックによってwithRouterを使用せずlocationやhistoryを使うといったこれまでできなかったことができるようになりました。いった値がHOCを使ったPropsで渡って来なくなったため、下記のようなコンポーネントの場合ユニットテストをするとRouterコンポーネントでラップされていないため、エラーが出るようになってしまいました。Pero解決策こういったエラーを解決するために、renderWithRouterというRouterコンポーネントでラップするユーティリティを用意します。Hooksを使ったコンポーネントのテストコードを書いていきます。})})先程用意したrenderWithRouterを使うことでテストができるようになりました。Hooksはv7.1.0から追加されたconnect()を使わずにコンポーネントでdispatch、stateを使うことができるフックです。前回同様、簡単なカウンターアプリを用意しました。Hooksを使用したコンポーネントは必然的にStoreと密結合になってしまいユニットテストではStoreのモックを用意しないとエラーが発生してしまいます。前回の記事でも書きましたが、Storeを用意するとユニットテストではなく、インテグレーションテストになってしまいます。今回はjest.mockを使いuseSelectorとuseDispatchのモックを作り対処します。これは前回の記事で使用したsinonでスタブを作ることでも実現できます。Hookを使っているコンポーネントでもユニットテストをすることができるようになりました。Router・ReduxのHooksが登場し、よりHooksが使いやすくなりました。