Nuxt.jsではJestを使ったテストを作成していたのですが、Next.jsに導入したことがなかったので導入方法を調べました。
Next.jsのドキュメントにJestの導入方法がまとまっていたのでここを参考にしました。
ライブラリの導入
yarn add -D jest @testing-library/react @testing-library/jest-dom react-test-renderer @types/react-test-renderer
必要なライブラリを導入します。
ドキュメントには記載がないですが、react-test-rendererも導入しました。
jest.config.jsの作成
jest.config.js
const nextJest = require('next/jest'); const createJestConfig = nextJest({ dir: './', }); const customJestConfig = { moduleDirectories: ['node_modules', '<rootDir>/'], testEnvironment: 'jest-environment-jsdom', }; module.exports = createJestConfig(customJestConfig);
プロジェクトのルートにjest.config.jsを作成します。
テストの作成
Btn.tsx
export default function Btn({ label = '', onClick = function () {} }) { return ( <div onClick={ onClick } className="btn"> <span>{ label }</span> </div> ); };
試しにこんな感じのボタンのテストを書いてみました。
Btn.text.ts
import { cleanup, fireEvent, render } from '@testing-library/react'; import renderer, { ReactTestRendererJSON } from 'react-test-renderer'; import Btn from '~/components/atoms/Btn'; afterEach(cleanup); test('Btn', () => { const { toJSON } = renderer.create(<Btn />); const tree = toJSON() as ReactTestRendererJSON; expect(tree).toMatchSnapshot(); // DOM構造に変更がないことを確認 expect(/btn/.test(tree.props.className)).toBe(true); // クラスが.btnであることを確認 }); test('label', () => { const label = 'label'; const { getByText } = render(<Btn label={label} />); expect(getByText(new RegExp(label))).toBeTruthy(); // ラベルがpropsと一致することを確認 }); test('click', () => { const onClick = jest.fn(); const { getByText } = render(<Btn onClick={onClick} label="label" />); fireEvent.click(getByText(/label/i)); expect(onClick).toHaveBeenCalledTimes(1); // クリックイベントが呼び出されたことを確認 });
DOM構造の確認、クラスの確認、propsで渡したlabelの確認、コールバックイベントが発火するかの確認をするとこんな感じになると思います。