Cómo configurar Jest con Next.js
Jest y React Testing Library se usan frecuentemente juntos para pruebas unitarias (Unit Testing) y pruebas de instantáneas (Snapshot Testing). Esta guía te mostrará cómo configurar Jest con Next.js y escribir tus primeras pruebas.
Bueno saber: Dado que los Componentes de Servicio
async
son nuevos en el ecosistema de React, Jest actualmente no los soporta. Aunque aún puedes ejecutar pruebas unitarias para Componentes de Servicio y Cliente sincrónicos, recomendamos usar pruebas E2E para componentesasync
.
Inicio rápido
Puedes usar create-next-app
con el ejemplo with-jest de Next.js para comenzar rápidamente:
npx create-next-app@latest --example with-jest with-jest-app
Configuración manual
Desde el lanzamiento de Next.js 12, Next.js ahora tiene configuración integrada para Jest.
Para configurar Jest, instala jest
y los siguientes paquetes como dependencias de desarrollo:
npm install -D jest jest-environment-jsdom @testing-library/react @testing-library/dom @testing-library/jest-dom ts-node @types/jest
# o
yarn add -D jest jest-environment-jsdom @testing-library/react @testing-library/dom @testing-library/jest-dom ts-node @types/jest
# o
pnpm install -D jest jest-environment-jsdom @testing-library/react @testing-library/dom @testing-library/jest-dom ts-node @types/jest
Genera un archivo básico de configuración de Jest ejecutando el siguiente comando:
npm init jest@latest
# o
yarn create jest@latest
# o
pnpm create jest@latest
Esto te guiará a través de una serie de preguntas para configurar Jest en tu proyecto, incluyendo la creación automática de un archivo jest.config.ts|js
.
Actualiza tu archivo de configuración para usar next/jest
. Este transformador tiene todas las opciones de configuración necesarias para que Jest funcione con Next.js:
import type { Config } from 'jest'
import nextJest from 'next/jest.js'
const createJestConfig = nextJest({
// Proporciona la ruta a tu aplicación Next.js para cargar next.config.js y archivos .env en tu entorno de prueba
dir: './',
})
// Agrega cualquier configuración personalizada para pasar a Jest
const config: Config = {
coverageProvider: 'v8',
testEnvironment: 'jsdom',
// Agrega más opciones de configuración antes de ejecutar cada prueba
// setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
}
// createJestConfig se exporta de esta manera para asegurar que next/jest pueda cargar la configuración de Next.js que es asíncrona
export default createJestConfig(config)
const nextJest = require('next/jest')
/** @type {import('jest').Config} */
const createJestConfig = nextJest({
// Proporciona la ruta a tu aplicación Next.js para cargar next.config.js y archivos .env en tu entorno de prueba
dir: './',
})
// Agrega cualquier configuración personalizada para pasar a Jest
const config = {
coverageProvider: 'v8',
testEnvironment: 'jsdom',
// Agrega más opciones de configuración antes de ejecutar cada prueba
// setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
}
// createJestConfig se exporta de esta manera para asegurar que next/jest pueda cargar la configuración de Next.js que es asíncrona
module.exports = createJestConfig(config)
Internamente, next/jest
está configurando automáticamente Jest para ti, incluyendo:
- Configurar
transform
usando el Compilador de Next.js. - Simulación automática de hojas de estilo (
.css
,.module.css
, y sus variantes scss), importaciones de imágenes ynext/font
. - Cargar
.env
(y todas sus variantes) enprocess.env
. - Ignorar
node_modules
de la resolución y transformaciones de pruebas. - Ignorar
.next
de la resolución de pruebas. - Cargar
next.config.js
para las banderas que habilitan transformaciones SWC.
Bueno saber: Para probar variables de entorno directamente, cárgalas manualmente en un script de configuración separado o en tu archivo
jest.config.ts
. Para más información, consulta Variables de entorno de prueba.
Configuración de Jest (con Babel)
Si optas por no usar el Compilador de Next.js y usas Babel en su lugar, necesitarás configurar Jest manualmente e instalar babel-jest
e identity-obj-proxy
además de los paquetes mencionados anteriormente.
Aquí están las opciones recomendadas para configurar Jest para Next.js:
module.exports = {
collectCoverage: true,
// en node 14.x el proveedor de cobertura v8 ofrece buena velocidad y un informe más o menos bueno
coverageProvider: 'v8',
collectCoverageFrom: [
'**/*.{js,jsx,ts,tsx}',
'!**/*.d.ts',
'!**/node_modules/**',
'!<rootDir>/out/**',
'!<rootDir>/.next/**',
'!<rootDir>/*.config.js',
'!<rootDir>/coverage/**',
],
moduleNameMapper: {
// Manejar importaciones CSS (con módulos CSS)
// https://jestjs.io/docs/webpack#mocking-css-modules
'^.+\\.module\\.(css|sass|scss)$': 'identity-obj-proxy',
// Manejar importaciones CSS (sin módulos CSS)
'^.+\\.(css|sass|scss)$': '<rootDir>/__mocks__/styleMock.js',
// Manejar importaciones de imágenes
// https://jestjs.io/docs/webpack#handling-static-assets
'^.+\\.(png|jpg|jpeg|gif|webp|avif|ico|bmp|svg)$': `<rootDir>/__mocks__/fileMock.js`,
// Manejar alias de módulos
'^@/components/(.*)$': '<rootDir>/components/$1',
// Manejar @next/font
'@next/font/(.*)': `<rootDir>/__mocks__/nextFontMock.js`,
// Manejar next/font
'next/font/(.*)': `<rootDir>/__mocks__/nextFontMock.js`,
// Deshabilitar server-only
'server-only': `<rootDir>/__mocks__/empty.js`,
},
// Agrega más opciones de configuración antes de ejecutar cada prueba
// setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
testPathIgnorePatterns: ['<rootDir>/node_modules/', '<rootDir>/.next/'],
testEnvironment: 'jsdom',
transform: {
// Usar babel-jest para transpilar pruebas con el preset next/babel
// 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)$',
],
}
Puedes aprender más sobre cada opción de configuración en la documentación de Jest. También recomendamos revisar la configuración de next/jest
para ver cómo Next.js configura Jest.
Manejo de hojas de estilo e importaciones de imágenes
Las hojas de estilo e imágenes no se usan en las pruebas, pero importarlas puede causar errores, por lo que necesitarán ser simuladas.
Crea los archivos de simulación referenciados en la configuración anterior - fileMock.js
y styleMock.js
- dentro de un directorio __mocks__
:
module.exports = 'test-file-stub'
module.exports = {}
Para más información sobre el manejo de recursos estáticos, consulta la documentación de Jest.
Manejo de fuentes
Para manejar fuentes, crea el archivo nextFontMock.js
dentro del directorio __mocks__
, y agrega la siguiente configuración:
module.exports = new Proxy(
{},
{
get: function getter() {
return () => ({
className: 'className',
variable: 'variable',
style: { fontFamily: 'fontFamily' },
})
},
}
)
Opcional: Manejo de importaciones absolutas y alias de módulos
Si tu proyecto está usando Alias de Módulos, necesitarás configurar Jest para resolver las importaciones haciendo coincidir la opción paths en el archivo jsconfig.json
con la opción moduleNameMapper
en el archivo jest.config.js
. Por ejemplo:
{
"compilerOptions": {
"module": "esnext",
"moduleResolution": "bundler",
"baseUrl": "./",
"paths": {
"@/components/*": ["components/*"]
}
}
}
moduleNameMapper: {
// ...
'^@/components/(.*)$': '<rootDir>/components/$1',
}
Opcional: Extender Jest con comparadores personalizados
@testing-library/jest-dom
incluye un conjunto de comparadores personalizados convenientes como .toBeInTheDocument()
que facilitan la escritura de pruebas. Puedes importar los comparadores personalizados para cada prueba agregando la siguiente opción al archivo de configuración de Jest:
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts']
setupFilesAfterEnv: ['<rootDir>/jest.setup.js']
Luego, dentro de jest.setup
, agrega la siguiente importación:
import '@testing-library/jest-dom'
import '@testing-library/jest-dom'
Bueno saber:
extend-expect
fue eliminado env6.0
, así que si estás usando@testing-library/jest-dom
antes de la versión 6, necesitarás importar@testing-library/jest-dom/extend-expect
en su lugar.
Si necesitas agregar más opciones de configuración antes de cada prueba, puedes agregarlas al archivo jest.setup
mencionado anteriormente.
Agrega un script de prueba a package.json
Finalmente, agrega un script de Jest test
a tu archivo package.json
:
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"test": "jest",
"test:watch": "jest --watch"
}
}
jest --watch
volverá a ejecutar las pruebas cuando un archivo cambie. Para más opciones de CLI de Jest, consulta la documentación de Jest.
Creando tu primera prueba
Tu proyecto ahora está listo para ejecutar pruebas. Crea una carpeta llamada __tests__
en el directorio raíz de tu proyecto.
Por ejemplo, podemos agregar una prueba para verificar si el componente <Home />
renderiza correctamente un encabezado:
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('renderiza un encabezado', () => {
render(<Home />)
const heading = screen.getByRole('heading', { level: 1 })
expect(heading).toBeInTheDocument()
})
})
Opcionalmente, agrega una prueba de instantánea (snapshot test) para rastrear cambios inesperados en tu componente:
import { render } from '@testing-library/react'
import Home from '../pages/index'
it('renderiza la página de inicio sin cambios', () => {
const { container } = render(<Home />)
expect(container).toMatchSnapshot()
})
Bueno saber: Los archivos de prueba no deben incluirse dentro del Enrutador de Páginas porque cualquier archivo dentro del Enrutador de Páginas se considera una ruta.
Ejecutando tus pruebas
Luego, ejecuta el siguiente comando para ejecutar tus pruebas:
npm run test
# o
yarn test
# o
pnpm test
Recursos adicionales
Para más información, puedes encontrar útiles estos recursos:
- Ejemplo de Next.js con Jest
- Documentación de Jest
- Documentación de React Testing Library
- Testing Playground - usa buenas prácticas de prueba para coincidir elementos.