Next.jsアプリケーションにJestを導入する方法は3つあります。1
- 「–example with-jest」オプション付きcreate-next-appコマンドでNext.jsを新規作成する
- Next.jsのRust Compilerを利用する
- Babelを利用する
Rust Compilerを利用する方法では、バージョン12以降のNext.jsに組み込まれているJestの設定を活用します。
今回はRust Compilerを利用して、TypeScriptを採用したNext.jsのアプリケーションにJestを導入する手順について紹介します。
検証環境はnext 12.1.4
、react 18.0.0
です。
目次
パッケージのインストール
$ yarn add -D jest jest-environment-jsdom @testing-library/react @testing-library/jest-dom
今回Jestの設定を追加するNext.jsにはTypeScriptが採用されていますが、Next.jsのRust Compilerを利用する場合はJestのドキュメントに記載されているts-jest
や@types/jest
のインストールは不要です。
jest.config.jsの作成
Next.js『setting-up-jest-with-the-rust-compiler』に記載されている設定を追加します。基本はデフォルトのままでOKです。
jest.config.js
const nextJest = require('next/jest')
const createJestConfig = nextJest({
// Provide the path to your Next.js app to load next.config.js and .env files in your test environment
dir: './',
})
// Add any custom config to be passed to Jest
const customJestConfig = {
// Add more setup options before each test is run
// setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
// if using TypeScript with a baseUrl set to the root directory then you need the below for alias' to work
moduleDirectories: ['node_modules', '<rootDir>/'],
testEnvironment: 'jest-environment-jsdom',
}
// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
module.exports = createJestConfig(customJestConfig)
(必要であれば)package.jsonのscriptsにエイリアスを追加
必要に応じて"test": "jest --watch"
や"test:coverage": "jest --collect-coverage"
のようなエイリアスをpackage.json
のscripts
プロパティに追記します。
動作確認
今回はコンポーネント(tsxファイル)とメソッド(tsファイル)のサンプルコードおよびテストコードを作成します。
サンプルコードの作成
src/components/Example.tsx
export const Example = () => (
<div data-testid={"Example"}>サンプルコンポーネント</div>
);
src/lib/example.ts
export const square = (num: number) => num * 2;
テストコードの作成
src/components/__tests__/Example.test.tsx
import { Example } from "src/components/Example";
import { render, screen } from "@testing-library/react";
describe("Example", () => {
it("表示されること", () => {
render(<Example />);
// data-testidを利用してテスト対象を抽出する方法
expect(screen.getByTestId("Example")).toBeInTheDocument();
expect(screen.getByTestId("Example")).toHaveTextContent("サンプル");
// テキストを利用してテスト対象を抽出する方法
expect(screen.getByText("サンプルコンポーネント")).toBeTruthy();
});
});
src/lib/__tests__/example.test.ts
import { square } from "../example";
describe("square", () => {
it("計算結果が正しいこと", () => {
const expected = 4;
expect(square(2)).toStrictEqual(expected);
});
});
Jestの実行
テストがパスすればOKです。
$ yarn jest
yarn run v1.22.17
warning ../../package.json: No license field
$ /Users/301184/git/next-sandbox/node_modules/.bin/jest
PASS src/components/__tests__/Example.test.tsx
PASS src/lib/__tests__/example.test.ts
Test Suites: 2 passed, 2 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 1.426 s
Ran all test suites.
✨ Done in 2.94s.
参考: Jest導入時のエラーについて
Jestを導入するNext.jsアプリケーションがすでにカスタマイズされている場合、今回の手順だと型エラーなどが発生する場合もあります。
そこで、いくつかエラーケースとその対処方法について紹介します。
『Cannot find name ‘describe’』と表示される
describe
, it
, expect
が型エラーになるケースです。
原因の1つとしてNext.jsアプリケーションのtsconfig.json
でtypes
の定義がすでにされていることが考えられます。
tsconfig.json
のtypes
にjest
を追加すると解決できます。
『Property ‘toHaveTextContent’ does not exist on type ‘JestMatchers‘』と表示される
toHaveTextContent
, toBeInTheDocument
が型エラーになるケースです。
原因の1つとしてNext.jsアプリケーションのtsconfig.json
でtypes
の定義がすでにされていることが考えられます。
tsconfig
に@testing-library/jest-dom
を追加すると解決できます。
テスト実行時『TypeError: expect(…).toBeInTheDocument is not a function』となる
import '@testing-library/jest-dom'
をテストコードに追加すると解決します。
src/components/__tests__/Example.test.tsx
import { Example } from "src/components/Example";
import { render, screen } from "@testing-library/react";
+ import '@testing-library/jest-dom';
describe("Example", () => {
(略)
あるいは、テストコードではなくセットアップファイルでインポートする方法もあります。セットアップファイルでインポートをする場合はjest.config.js
で当該ファイルを読み込むように修正します。
jest.setup.js
import '@testing-library/jest-dom';
jest.config.js
const customJestConfig = {
// Add more setup options before each test is run
- // setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
+ setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
さいごに
Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!
参考資料
- Jest『Getting Started』
- Next.js『Jest and React Testing Library』
- Next.js 12でJestの設定がかなり楽になった
- Next.js + TypeScriptのプロジェクトにJestを導入する
- Cannot find name ‘describe’. Do you need to install type definitions for a test runner?
- Fix – Cannot find name ‘describe’ Error in TypeScript
- Property ‘toBeInTheDocument’ does not exist on type ‘Matchers
‘ - react-testing-library why is toBeInTheDocument() not a function