はじめに
Rails 7とReactを使ったサンプルアプリがあったので勉強がてら実装してみました。
コンパクトにまとまったいい記事なのですが、テストが書かれていなかったので実装してみることにしました。なお、ここに書いているのはいわゆるベストプラクティスではなく、こうしたらとりあえず動いたというレベルで見ていただけると幸いです。
セットアップ
Jestを含めた各種ライブラリをインストールすることから始めます。Jestのサイトに以下の記事があったのでそれを参考にします。
package.json
にて以下の記述を追加しておくとnpm run test
でテストが実行できるので追記しておきます。
"scripts": { // ↓を追記 "test": "jest" },
自分はテストをapp/javascript/__tests__
に置くことにしたので、package.json
にjestの設定を記述します。
"jest": { "roots": [ "<rootDir>/app/javascript" ] }
package.json
ではなくjestの設定ファイルとしてjest.config.js
を作成しても良いかと思います。
テストの書き方
各componentsに対してテストを書きます。DOMを操作するもののテストについては、React Testing Libraryを使うようです。
他にもJest 28からの仕様変更によりjest-environment-jsdom
の設定が必要でした。
React Testing Libraryを使ったテストを書く場合、以下のドキュメントに書かれているクエリを発行してtesting-library/jest-domでのマッチャーを使ってテストを実装するようです。
一番簡単なテストとしては以下のような実装となりました。
/** * @jest-environment jsdom */ import {render, screen} from "@testing-library/react"; import EventNotFound from "../components/EventNotFound"; import '@testing-library/jest-dom/extend-expect'; describe('EventNotFound', () => { test('renders EventNotFound component', () => { render(<EventNotFound />); expect(screen.getByText('Event not found!')).toBeInTheDocument(); }) });
テストが失敗する例
context of a componentが出る
上記のような書き方でテストを実装すると、context of a <Router> component
というエラーが出てしまうケースがあります。この時は、MemoryRouter
というものを使ってテストを書きます。
以下のようなテストになりました。
/** * @jest-environment jsdom */ import Header from "../components/Header"; import {render, screen} from "@testing-library/react"; import { MemoryRouter as Router } from "react-router-dom"; import '@testing-library/jest-dom/extend-expect'; test('renders Header', () => { render( <Router> <Header /> </Router> ); expect(screen.getByText('Event Manager')).toBeInTheDocument(); })
cssのimportにてSyntaxErrorが出る
テスト対象のcomponentにてimport 'pikaday/css/pikaday.css';
というようにCSSを読み込んでいるとSyntaxErrorが出ました。この事象に対してはstackoverflowに類似の記事があったので、それを参考に解決します。
具体的には、package.json
にてJestの設定を追記します。
"jest": { "roots": [ "<rootDir>/app/javascript" ], "moduleNameMapper": { "\\.(css|less|sass|scss)$": "<rootDir>/app/javascript/__mocks__/styleMock.js" } }
その後、app/javascript/__mocks__/styleMock.js
というファイルを作成します。中身は以下の通りほぼ空です。
module.exports = {};
これでSyntaxErrorは出なくなりました。