Setting up Jest with Next.js
Jest と React Testing Library は、頻繁にUnit TestingとSnapshot 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 の例とともに利用して、迅速に開始することができます:
npx create-next-app@latest --example with-jest with-jest-app
Manual setup
Next.js 12 のリリース以来、Next.js には Jest 用の組み込み設定が標準で付属しています。
Jest をセットアップするために、Jest
と以下のパッケージをdev
依存関係としてインストールします:
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 設定ファイルを生成します:
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 が含まれています。
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)
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 があります:
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__
ディレクトリ内に作成します:
module.exports = 'test-file-stub'
module.exports = {}
詳細については、静的アセットの取り扱いについて、Jest Docs をご参照ください。
Handling Fonts
フォントを扱うには、__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 がインポートを解決できるように設定する必要があります。例えば:
{
"compilerOptions": {
"module": "esnext",
"moduleResolution": "bundler",
"baseUrl": "./",
"paths": {
"@/components/*": ["components/*"]
}
}
}
moduleNameMapper: {
// ...
'^@/components/(.*)$': '<rootDir>/components/$1',
}
Optional: Extend Jest with custom matchers
@testing-library/jest-dom
は、.toBeInTheDocument()
のような便利なカスタムマッチャー を含んでおり、テストの記述を容易にします。次のオプションを Jest の設定ファイルに追加することで、すべての test でカスタムマッチャーを import することができます。
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts']
setupFilesAfterEnv: ['<rootDir>/jest.setup.js']
その後、jest.setup.ts
の中に次の import を追加します:
import '@testing-library/jest-dom'
import '@testing-library/jest-dom'
Good to know:
extend-expect
はv6.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
スクリプトを追加してください:
{
"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 を追加することができます。
export default function Home() {
return <h1>Home</h1>
}
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 を追加してください:
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
そして、テストを実行するために、次のコマンドを実行してください:
npm run test
# or
yarn test
# or
pnpm test
Additional Resources
さらなる読書のために、これらのリソースが役立つかもしれません:
- Next.js と Jest の例
- Jest Docs
- React Testing Library Docs
- Testing Playground - 要素を照合するために良いテスト手法を使用してください。