Next.js(TypeScript)にJestを設定する方法

JavaScript

Next.jsアプリケーションにJestを導入する方法は3つあります。1

Next.jsにJestを導入する方法
  • 「–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.4react 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.jsonscriptsプロパティに追記します。

動作確認

今回はコンポーネント(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.jsontypesの定義がすでにされていることが考えられます。
tsconfig.jsontypesjestを追加すると解決できます。

『Property ‘toHaveTextContent’ does not exist on type ‘JestMatchers‘』と表示される

toHaveTextContent, toBeInTheDocumentが型エラーになるケースです。

原因の1つとしてNext.jsアプリケーションのtsconfig.jsontypesの定義がすでにされていることが考えられます。
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)やってます。フォローしてもらえるとうれしいです!

参考資料