Configuración de Jest con Next.js
Configura Jest con Next.js usando el preset oficial next/jest para soporte de TypeScript y alias de rutas sin configuración adicional.
Receta
Tarjeta de referencia rápida — lista para copiar y pegar.
# Instalar dependencias
npm install -D jest @testing-library/react @testing-library/jest-dom @testing-library/user-event jest-environment-jsdom ts-node @types/jest// jest.config.ts
import type { Config } from "jest";
import nextJest from "next/jest";
const createJestConfig = nextJest({
dir: "./", // Path to your Next.js app (loads next.config.js and .env)
});
const config: Config = {
testEnvironment: "jsdom",
setupFilesAfterSetup: ["<rootDir>/jest.setup.ts"],
moduleNameMapper: {
"^@/(.*)$": "<rootDir>/src/$1",
},
};
export default createJestConfig(config);// jest.setup.ts
import "@testing-library/jest-dom";// scripts de package.json
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage"
}
}Cuándo usarlo: Cuando ya tienes una configuración de Jest, necesitas plugins específicos de Jest o prefieres el ecosistema maduro de Jest con integración completa de Next.js mediante next/jest.
Ejemplo funcional
// src/components/counter.tsx
"use client";
import { useState } from "react";
export function Counter({ initial = 0 }: { initial?: number }) {
const [count, setCount] = useState(initial);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount((c) => c + 1)}>Increment</button>
<button onClick={() => setCount((c) => c - 1)}>Decrement</button>
</div>
);
}// src/components/counter.test.tsx
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { Counter } from "./counter";
describe("Counter", () => {
it("renders with initial count", () => {
render(<Counter initial={5} />);
expect(screen.getByText("Count: 5")).toBeInTheDocument();
});
it("increments on click", async () => {
const user = userEvent.setup();
render(<Counter />);
await user.click(screen.getByRole("button", { name: "Increment" }));
expect(screen.getByText("Count: 1")).toBeInTheDocument();
});
it("decrements on click", async () => {
const user = userEvent.setup();
render(<Counter initial={3} />);
await user.click(screen.getByRole("button", { name: "Decrement" }));
expect(screen.getByText("Count: 2")).toBeInTheDocument();
});
});Lo que demuestra:
next/jestgestiona las transformaciones de TypeScript y la simulación de módulos CSS automáticamenteuserEvent.setup()para simular interacciones de usuario realistas- Consultas por rol accesible y texto
Profundización
Cómo funciona
next/jestcrea una configuración de Jest que se integra con el compilador SWC de Next.js para transformaciones rápidas (sin necesidad de Babel)- Simula automáticamente módulos CSS, importaciones de imágenes y
next/fontpara que no rompan los tests - La opción
dirindica a Next.js dónde encontrarnext.config.jspara cargar variables de entorno y alias de módulos setupFilesAfterSetupse ejecuta después de que el framework de tests se instala en el entorno — aquí es donde cargas los matchers de@testing-library/jest-dommoduleNameMapperreplica los alias de rutas detsconfig.jsonpara que@/components/...se resuelva correctamente
Variaciones
Configuración de transformación para tipos de archivo específicos:
// jest.config.ts — next/jest handles most transforms, but you can add custom ones
const config: Config = {
transform: {
"\\.svg$": "<rootDir>/test/svg-transform.ts",
},
};Ejecutar un subconjunto de tests:
# Ejecutar tests que coincidan con un patrón
jest --testPathPattern="components"
# Ejecutar un solo archivo
jest src/components/counter.test.tsx
# Ejecutar tests que coincidan con un nombre
jest -t "increments"Recopilar cobertura:
// jest.config.ts
const config: Config = {
collectCoverageFrom: [
"src/**/*.{ts,tsx}",
"!src/**/*.d.ts",
"!src/**/index.ts",
],
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80,
},
},
};Notas de TypeScript
// If using ts-node for jest.config.ts, ensure tsconfig allows it
// tsconfig.json
{
"compilerOptions": {
"types": ["jest", "@testing-library/jest-dom"]
}
}
// For ESM projects, you may need:
// jest.config.ts
// export default createJestConfig(config) — next/jest handles ESM interopErrores comunes
-
next/jestrequiere Next.js 13.1+ — Las versiones anteriores carecen de la integración de Jest basada en SWC. Solución: Actualiza Next.js o configura Babel manualmente. -
Errores de importación de CSS — Si ves
SyntaxError: Unexpected tokenen archivos.css,next/jestno se está aplicando correctamente. Solución: Asegúrate de quecreateJestConfigenvuelva tu configuración y quedirapunte a la raíz de tu proyecto. -
Fallos con paquetes ESM — Algunos paquetes npm se distribuyen solo en ESM y Jest usa CommonJS por defecto. Solución: Añádelos a
transformIgnorePatterns:const config: Config = { transformIgnorePatterns: [ "node_modules/(?!(swiper|ky|nanoid)/)", ], }; -
Arranque lento de los tests — Jest tiene un coste de arranque mayor que Vitest debido a la resolución de módulos. Solución: Usa el modo
--watchdurante el desarrollo para cachear transformaciones entre ejecuciones. -
setupFilesAfterSetupvssetupFiles—setupFilesse ejecuta antes de que cargue el framework de tests;setupFilesAfterSetupse ejecuta después. Los matchers de jest-dom deben ir ensetupFilesAfterSetup. Solución: UsasetupFilesAfterSetuppara@testing-library/jest-dom.
Alternativas
| Alternativa | Úsala cuando | No la uses cuando |
|---|---|---|
| Vitest | Quieres un modo watch más rápido, ESM nativo y transformaciones basadas en Vite | Necesitas plugins específicos de Jest o tienes una suite grande de Jest existente |
@swc/jest | Necesitas transformaciones SWC sin el preset de Next.js | Estás usando Next.js (usa next/jest en su lugar) |
| Bun test | Usas Bun como runtime y quieres tests integrados | Necesitas el ecosistema de matchers y plugins de Jest |
Preguntas frecuentes
¿Qué hace next/jest que una configuración de Jest simple no hace?
- Se integra con el compilador SWC de Next.js para transformaciones rápidas de TypeScript.
- Simula automáticamente módulos CSS, importaciones de imágenes y
next/font. - Carga
next.config.jspara variables de entorno y alias de módulos.
¿Cuál es la diferencia entre setupFiles y setupFilesAfterSetup?
setupFilesse ejecuta antes de que cargue el framework de tests.setupFilesAfterSetupse ejecuta después. Los matchers de jest-dom deben ir ensetupFilesAfterSetupporque extienden elexpectde Jest.
¿Por qué obtengo SyntaxError: Unexpected token en importaciones de CSS?
Esto significa que next/jest no se está aplicando correctamente. Asegúrate de que createJestConfig envuelva tu configuración y que la opción dir apunte a la raíz de tu proyecto.
¿Cómo gestiono paquetes npm solo ESM en Jest?
Añádelos a transformIgnorePatterns:
transformIgnorePatterns: [
"node_modules/(?!(swiper|ky|nanoid)/)",
],¿Por qué el arranque de Jest es lento comparado con Vitest?
- Jest tiene mayor sobrecarga de resolución de módulos y transformación.
- Usa el modo
--watchdurante el desarrollo para cachear transformaciones entre ejecuciones. - Considera Vitest si el tiempo de arranque es una preocupación crítica.
Trampa: ¿Qué ocurre si se usa next/jest con Next.js por debajo de la versión 13.1?
No funcionará. La integración de Jest basada en SWC requiere Next.js 13.1+. Para versiones anteriores, configura Babel manualmente.
¿Cómo ejecuto solo los tests que coincidan con un nombre específico?
jest -t "increments"Esto ejecuta solo los casos de test cuyos nombres coincidan con la cadena "increments".
¿Cómo configuro umbrales de cobertura en Jest?
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80,
},
},¿Cómo añado tipos de TypeScript para los globals de Jest y los matchers de jest-dom?
Añade ambos a tu tsconfig.json:
{
"compilerOptions": {
"types": ["jest", "@testing-library/jest-dom"]
}
}Trampa: ¿Por qué moduleNameMapper no lee automáticamente de tsconfig.json?
Jest no analiza los alias de rutas de tsconfig.json. Debes replicarlos en moduleNameMapper o usar next/jest, que gestiona parte de la resolución de alias mediante la opción dir.
¿Puedo usar transformaciones personalizadas para tipos de archivo específicos como SVG?
Sí. Añade una entrada transform en tu configuración de Jest:
transform: {
"\\.svg$": "<rootDir>/test/svg-transform.ts",
},¿Cuál es la forma recomendada de tipar jest.config.ts?
Importa el tipo Config de Jest:
import type { Config } from "jest";
const config: Config = { /* ... */ };Relacionado
- Configuración de Vitest con Next.js — la alternativa más rápida
- Fundamentos de React Testing Library — consultas y aserciones
- Probar componentes — patrones para tests de componentes
- Simulación en tests — simular módulos y APIs