【Next.js】jestを使ったユニットテストを導入する(TypeScript利用)

スポンサーリンク
Next.jsロゴ React.js/Next.js

環境

  • next 13.2.1
  • jest 29.5.0

参考ページ

今回の記事は、Next.jsのテストに関するページをもとに作成している。

Optimizing: Testing | Next.js
Learn how to set up Next.js with three commonly used testing tools — Cypress, Playwright, Jest, and React Testing Librar...

テスト対象のコンポーネント

今回のテスト対象コンポーネントは以下。

ボタンと言いつつ、ただのh3タグが配置されているだけのものである。

./src/components/ButtonSample.tsx

export default function ButtonSample() {
  return <h3>This is button sample</h3>;
}

手順

1. 必要なライブラリをインストール

jestを中心に、Reactのテストに必要なライブラリたちをインストールする。

$ npm install --save-dev jest jest-environment-jsdom @testing-library/react @testing-library/jest-dom

Reactのテストをいい感じに行うために、
「testing-library」に便利なツール郡が含まれているので
それらをインストールするのがポイントである。

2. jest.config.mjsファイルを作成する

jestの設定ファイルであるjest.config.mjsを作成する。

これは一旦公式ページのコピペ通りで良い。(後で少し修正する)

./jest.config.mjs

import nextJest from 'next/jest.js'
 
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
/** @type {import('jest').Config} */
const config = {
  // Add more setup options before each test is run
  // setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
 
  testEnvironment: 'jest-environment-jsdom',
}
 
// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
export default createJestConfig(config)

3. テストコードを作成する

慣習的に「コンポーネント名.test.tsx」で作成することが多い。

配置するディレクトリに制約はない。

./src/components/ButtonSample.test.tsx

import { render, screen } from "@testing-library/react";
import ButtonSample from "./ButtonSample";
import "@testing-library/jest-dom";

describe("ButtonSampleのテスト", () => {
  it("renders a heading", () => {
    render(<ButtonSample />);

    // 見出し要素を名前を指定して取得
    const heading = screen.getByRole("heading", {
      name: "This is button sample",
    });

    // 取得した要素がドキュメント内に存在したらテストOK
    expect(heading).toBeInTheDocument();
  });
});

4. テスト用のnpm-scriptを作成

package.jsonにテスト実行用のコマンドを追加する。

"test": "jest"だけあれば十分だが、watchオプションを指定したコマンドも用意しておくと後々便利。

{
  // 略
  "scripts": {
    "dev": "next dev",
    "test": "jest",
    "test:watch": "jest --watch"
  },
  // 略
}

5. テスト実行

あとは作成したnpm-scriptを実行するのみ。

$ npm run test

> nextjs-starter@0.1.0 test
> jest

warn  - You have enabled experimental feature (appDir) in next.config.js.
warn  - Experimental features are not covered by semver, and may cause unexpected or broken application behavior. Use at your own risk.
info  - Thank you for testing `appDir` please leave your feedback at https://nextjs.link/app-feedback

 PASS  src/components/ButtonSample.test.tsx
  ButtonSampleのテスト
    ✓ renders a heading (92 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.719 s, estimated 1 s
Ran all test suites.

テストがパスしていることが分かる。

トラブルシューティング

テスト実行した時、以下のようなエラーが発生する場合がある。

Cannot find module '@/app/use-context-sample/themeContext' from 'src/components/ButtonSample.tsx'

この原因は「@/」という絶対パスをテストコードで解決できていないことが原因である。

そのため、jest.config.mjsに以下の記述を追加する必要がある。

import nextJest from "next/jest.js";

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
/** @type {import('jest').Config} */
const config = {
  // Add more setup options before each test is run
  // setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],

  testEnvironment: "jest-environment-jsdom",

  // これを追加する!
  moduleNameMapper: {
    "^@/(.*)$": "<rootDir>/src/$1",
  },
};

// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
export default createJestConfig(config);

参考:https://nextjs.org/docs/pages/building-your-application/optimizing/testing#creating-your-tests

まとめ

  • 公式ドキュメント通りに進めれば基本は問題ない
  • @に関するエラーが発生した場合は、テストコードでパスが解決できていないことが原因
タイトルとURLをコピーしました