Lang x Lang

Setting up Jest with Next.js

Jest と React Testing Library は、頻繁にUnit TestingSnapshot Testingのために一緒に使用されます。このガイドでは、Jest を Next.js と設定する方法と、最初のテストの書き方をご紹介します。

Good to know: async Server Components は React エコシステムにとって新しいため、現在 Jest ではサポートされていません。同期的な Server および Client Components に対するユニットテストは引き続き実行できますが、asyncコンポーネントに対してはE2E テストを使用することをお勧めします。

Quickstart

あなたは create-next-app を Next.js with-jest の例とともに利用して、迅速に開始することができます:

Terminal
npx create-next-app@latest --example with-jest with-jest-app

Manual setup

Next.js 12 のリリース以来、Next.js には Jest 用の組み込み設定が標準で付属しています。

Jest をセットアップするために、Jestと以下のパッケージをdev依存関係としてインストールします:

Terminal
npm install -D jest jest-environment-jsdom @testing-library/react @testing-library/jest-dom
# or
yarn add -D jest jest-environment-jsdom @testing-library/react @testing-library/jest-dom
# or
pnpm install -D jest jest-environment-jsdom @testing-library/react @testing-library/jest-dom

次のコマンドを実行して、基本的な Jest 設定ファイルを生成します:

Terminal
npm init jest@latest
# or
yarn create jest@latest
# or
pnpm create jest@latest

これにより、プロジェクトのための Jest を設定するための一連のプロンプトを通過します。これには、自動的にjest.config.ts|jsファイルを作成することも含まれます。

next/jestを使用するように config ファイルを更新してください。このトランスフォーマーには、Next.js で動作するための Jest のすべての必要な設定 options が含まれています。

jest.config.ts
import type { Config } from 'jest'
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
const config: Config = {
  coverageProvider: 'v8',
  testEnvironment: 'jsdom',
  // Add more setup options before each test is run
  // setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
}

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

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

// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
module.exports = createJestConfig(config)

ボンネットの下で、 next/jestは自動的に Jest をあなたのために設定しています。これには以下が含まれます:

  • transformの設定を行う、Next.js Compilerを用いて
  • 自動モックスタイルシート(.css.module.css、およびそれらの scss バリアント)、image インポート、およびnext/font
  • Loading.env(およびすべてのバリアント)をprocess.envにロードする
  • node_modulesを無視し、test の解決と変換から除外します
  • .nextを無視し、test を解決
  • Loading というフラグを有効にするためのnext.config.jsを読み込み、SWC トランスフォームを可能にします

Good to know: Test Environment Variables を直接ロードするには、別のセットアップスクリプトや jest.config.ts ファイルで手動で読み込んでください。詳細については、test environment variablesを参照してください。

Setting up Jest (with Babel)

あなたがNext.js Compilerの選択を辞めて代わりに Babel を使う場合、手動で Jest を設定し、上記のパッケージに加えて、babel-jest および identity-obj-proxy をインストールする必要があります。

ここに Next.js の Jest を設定するための推奨される options があります:

jest.config.js
module.exports = {
  collectCoverage: true,
  // on node 14.x coverage provider v8 offers good speed and more or less good report
  coverageProvider: 'v8',
  collectCoverageFrom: [
    '**/*.{js,jsx,ts,tsx}',
    '!**/*.d.ts',
    '!**/node_modules/**',
    '!<rootDir>/out/**',
    '!<rootDir>/.next/**',
    '!<rootDir>/*.config.js',
    '!<rootDir>/coverage/**',
  ],
  moduleNameMapper: {
    // Handle CSS imports (with CSS modules)
    // https://jestjs.io/docs/webpack#mocking-css-modules
    '^.+\\.module\\.(css|sass|scss)$': 'identity-obj-proxy',

    // Handle CSS imports (without CSS modules)
    '^.+\\.(css|sass|scss)$': '<rootDir>/__mocks__/styleMock.js',

    // Handle image imports
    // https://jestjs.io/docs/webpack#handling-static-assets
    '^.+\\.(png|jpg|jpeg|gif|webp|avif|ico|bmp|svg)$/i': `<rootDir>/__mocks__/fileMock.js`,

    // Handle module aliases
    '^@/components/(.*)$': '<rootDir>/components/$1',

    // Handle @next/font
    '@next/font/(.*)': `<rootDir>/__mocks__/nextFontMock.js`,
    // Handle next/font
    'next/font/(.*)': `<rootDir>/__mocks__/nextFontMock.js`,
    // Disable server-only
    'server-only': `<rootDir>/__mocks__/empty.js`,
  },
  // Add more setup options before each test is run
  // setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
  testPathIgnorePatterns: ['<rootDir>/node_modules/', '<rootDir>/.next/'],
  testEnvironment: 'jsdom',
  transform: {
    // Use babel-jest to transpile tests with the next/babel preset
    // https://jestjs.io/docs/configuration#transform-objectstring-pathtotransformer--pathtotransformer-object
    '^.+\\.(js|jsx|ts|tsx)$': ['babel-jest', { presets: ['next/babel'] }],
  },
  transformIgnorePatterns: [
    '/node_modules/',
    '^.+\\.module\\.(css|sass|scss)$',
  ],
}

各設定オプションについての詳細は、Jest ドキュメント で学ぶことができます。また、Next.js が Jest をどのように設定するかを確認するために、next/jest 設定 のレビューもお勧めします。

スタイルシートと image インポートの処理

スタイルシートや画像はテストで使用されませんが、それらをインポートすると error が発生する可能性があるので、モック化する必要があります。

上記の設定で参照されるモックファイル - fileMock.js および styleMock.js - を __mocks__ ディレクトリ内に作成します:

__mocks__/fileMock.js
module.exports = 'test-file-stub'
__mocks__/styleMock.js
module.exports = {}

詳細については、静的アセットの取り扱いについて、Jest Docs をご参照ください。

Handling Fonts

フォントを扱うには、__mocks__ディレクトリ内にnextFontMock.jsファイルを作成し、次の設定を追加します:

__mocks__/nextFontMock.js
module.exports = new Proxy(
  {},
  {
    get: function getter() {
      return () => ({
        className: 'className',
        variable: 'variable',
        style: { fontFamily: 'fontFamily' },
      })
    },
  }
)

Optional: Handling Absolute Imports and Module Path Aliases

あなたのプロジェクトがModule Path Aliasesを使用している場合、jsconfig.jsonファイルの paths オプションと、jest.config.jsファイルのmoduleNameMapperオプションを一致させることで、Jest がインポートを解決できるように設定する必要があります。例えば:

tsconfig.json
{
  "compilerOptions": {
    "module": "esnext",
    "moduleResolution": "bundler",
    "baseUrl": "./",
    "paths": {
      "@/components/*": ["components/*"]
    }
  }
}
jest.config.js
moduleNameMapper: {
  // ...
  '^@/components/(.*)$': '<rootDir>/components/$1',
}

Optional: Extend Jest with custom matchers

@testing-library/jest-domは、.toBeInTheDocument()のような便利なカスタムマッチャー を含んでおり、テストの記述を容易にします。次のオプションを Jest の設定ファイルに追加することで、すべての test でカスタムマッチャーを import することができます。

jest.config.ts
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts']
jest.config.js
setupFilesAfterEnv: ['<rootDir>/jest.setup.js']

その後、jest.setup.tsの中に次の import を追加します:

jest.setup.ts
import '@testing-library/jest-dom'
jest.setup.js
import '@testing-library/jest-dom'

Good to know:extend-expectv6.0で削除されました 。したがって、 version 6 より前に @testing-library/jest-domを使用している場合、代わりに @testing-library/jest-dom/extend-expectを import する必要があります。

もし各 test の前に更に options を設定する必要がある場合は、それらを上記のjest.setup.jsファイルに追加することができます。

Add a test script to package.json

最後に、package.jsonファイルに Jest のtestスクリプトを追加してください:

package.json
{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "test": "jest",
    "test:watch": "jest --watch"
  }
}

jest --watchは、ファイルが変更されたときにテストを再実行します。より多くの Jest CLI options については、Jest Docs を参照してください。

あなたの最初の test を作成する

あなたのプロジェクトはテストを実行する準備ができている。プロジェクトの root ディレクトリに__tests__という名前のフォルダを作成してください。

例えば、<Home /> component が見出しを正常にレンダリングするかどうかを確認するための test を追加することができます。

pages/index.js
export default function Home() {
  return <h1>Home</h1>
}
__tests__/index.test.js
import '@testing-library/jest-dom'
import { render, screen } from '@testing-library/react'
import Home from '../pages/index'

describe('Home', () => {
  it('renders a heading', () => {
    render(<Home />)

    const heading = screen.getByRole('heading', { level: 1 })

    expect(heading).toBeInTheDocument()
  })
})

オプショナルで、あなたの component で予期しない変更を追跡するためのスナップショット test を追加してください:

__tests__/snapshot.js
import { render } from '@testing-library/react'
import Home from '../pages/index'

it('renders homepage unchanged', () => {
  const { container } = render(<Home />)
  expect(container).toMatchSnapshot()
})

Good to know: Test ファイルは、 Pages Router 内に含めるべきではありません。なぜなら、 Pages Router 内の任意のファイルは、 routes と見なされるからです。

Running your tests

そして、テストを実行するために、次のコマンドを実行してください:

Terminal
npm run test
# or
yarn test
# or
pnpm test

Additional Resources

さらなる読書のために、これらのリソースが役立つかもしれません:

当社サイトでは、Cookie を使用しています。各規約をご確認の上ご利用ください:
Cookie Policy, Privacy Policy および Terms of Use