EDIT: A new version is available for this article: How to setup Jest in Next 15 + eslint.
Since version 12, Next.js has build in configuration for Jest. The documentation is pretty clear how to get started. Install the npm packages (jest, jest-environment-jsdom, @testing-library/react, @testing-library/jest-dom) and add a jest.config.js file:
// 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
/** @type {import('jest').Config} */
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)
But this default configuration isn't optimal. You can make your workflow more easy with the following tips.
1. Auto include jest-dom in every test
jest-dom is a library with a whole series of usefull matcher functions. To use these matchers, you need to import jest-dom in every test file.
import '@testing-library/jest-dom/extend-expect'
You can automate this import by adding following line in jest.config.js (This line is commented out in the above example provided by Next.js):
// jest.config.js
setupFilesAfterEnv: ['<rootDir>/jest.setup.js']
And then making a new file: jest.setup.js
// jest.setup.js
import '@testing-library/jest-dom/extend-expect'
And that's all, no more manually writing an import line for jest-dom in every test file.
2. Auto clear all mocks
To prevent different tests from polluting each other, you can call jest.clearAllMocks(). You can call this manually in each test or inside a lifecycle hook like beforeEach.
But, when you have a lot of tests, this can grow tiresome. So, let's automate it. This is really easy. We add clearMocks: true to Jest.config.js:
// 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',
// automate clear mocks
clearMocks: true,
}
// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
module.exports = createJestConfig(customJestConfig)
And we're done.
3. Use eslint-plugin-testing-library
It's a good habit to let eslint help you out when you're coding. There is a specific eslint library for testing: eslint-plugin-testing-library Here is how you configure it.
First, install the package:
npm install --save-dev eslint-plugin-testing-library
Then go to the file .eslintrc.json
{
"extends": "next/core-web-vitals"
}
Add the following lines:
{
"extends": ["next/core-web-vitals", "plugin:testing-library/react"],
"plugins": ["testing-library"]
}
And we are done. Eslint will now happily yell at you whenever you make a mistake.
Top comments (0)