Cuando las pruebas fallan por dependencias como archivos de estilos o el estado global de la aplicación, los mocks se convierten en la herramienta esencial para simular esas funcionalidades y permitir que los tests se ejecuten sin errores. Aquí se explica paso a paso cómo crear mocks para estilos CSS y para toda la estructura de Redux y React Router en un proyecto React.
¿Cómo crear un mock de estilos para que Jest ignore los archivos CSS?
El problema inicial surge porque Jest no puede interpretar archivos de estilos como .css o .styl. La solución es crear un mock que retorne un módulo vacío cada vez que el componente intente importar estilos.
Primero se crea la carpeta estándar __mocks__ dentro del proyecto [01:00]. Dentro de esta carpeta se genera un archivo llamado styleMock.js con un contenido mínimo:
javascript
module.exports = {};
Este archivo simplemente exporta un objeto vacío, indicándole a Jest que no necesita procesar esos estilos.
¿Cómo se configura moduleNameMapper en package.json?
Para que Jest sepa cuándo usar este mock, se añade la propiedad moduleNameMapper dentro de la configuración de Jest en package.json [01:42]. La configuración luce así:
"jest": {
"moduleNameMapper": {
"\.(styl|css)$": "<rootDir>/src/mocks/styleMock.js"
}
}
- La expresión regular
\\.(styl|css)$ captura cualquier importación que termine en .styl o .css.
- El símbolo
$ al final indica que se trata de una extensión de archivo.
<rootDir> apunta a la raíz del proyecto.
Al ejecutar npm run test después de esta configuración, Jest ignora los estilos y las pruebas pasan correctamente [03:08].
¿Cómo probar que un componente renderiza un título específico?
Con los estilos resueltos, se puede crear una segunda prueba dentro de la misma suite para verificar que el componente Footer muestra el título esperado [03:25].
javascript
test('render del título', () => {
expect(footer.find('.footer-title').text()).toEqual('Platzi Store');
});
- Se usa el método
.find() de Enzyme para localizar un elemento por su clase CSS.
- El método
.text() extrae el contenido de texto del elemento encontrado.
- toEqual compara que el valor sea exactamente
'Platzi Store'.
¿Por qué es importante definir variables al nivel de la suite?
Un error común es declarar la variable footer solo dentro de una prueba individual. Cuando otra prueba intenta acceder a esa misma variable, el test falla porque no está definida en ese scope [04:28].
La solución es elevar la declaración al nivel superior del describe, para que todas las pruebas dentro de la suite puedan reutilizarla:
javascript
describe('Footer', () => {
const footer = shallow(<Footer />);
test('render del componente', () => { /* ... / });
test('render del título', () => { / ... */ });
});
Esto garantiza que cada test acceda a la misma instancia montada del componente.
¿Cómo crear un ProviderMock para componentes conectados a Redux?
Componentes como el Header usan connect de Redux y reciben props desde el estado global. Al intentar probarlos sin un store, Jest lanza un error [05:30]. La solución es construir un ProviderMock que simule toda la estructura necesaria.
Dentro de __mocks__ se crea el archivo ProviderMock.js con las siguientes importaciones [06:18]:
javascript
import React from 'react';
import { createStore } from 'redux';
import { Router } from 'react-router-dom';
import { Provider } from 'react-redux';
import { createBrowserHistory } from 'history';
import initialState from '../initialState';
import reducer from '../reducers';
- createStore genera un store de Redux con el reducer y el estado inicial del proyecto.
- createBrowserHistory permite simular el historial de navegación que usa React Router.
- Provider envuelve los componentes para darles acceso al store.
- Router envuelve los componentes para simular la navegación de rutas.
Luego se construye el mock completo [07:50]:
javascript
const store = createStore(reducer, initialState);
const history = createBrowserHistory();
const ProviderMock = (props) => (
<Provider store={store}>
<Router history={history}>
{props.children}
</Router>
</Provider>
);
export default ProviderMock;
props.children representa cualquier componente que se pase como hijo, permitiendo envolver los elementos que se desean probar.
- Esta estructura replica la configuración real de la aplicación: un Provider con su store y un Router con su historial.
Con este ProviderMock listo, cualquier componente conectado a Redux o que dependa de rutas puede montarse en las pruebas sin errores. ¿Ya has implementado mocks en tus proyectos? Comparte tu experiencia en los comentarios.