Resumen

Verificar que los reducers funcionan correctamente es una parte fundamental del testing en aplicaciones React que manejan estado global. Aquí se aborda paso a paso cómo crear pruebas unitarias para un reducer, validando tanto el estado inicial como la acción de agregar un producto al carrito.

¿Cómo se estructura el archivo de pruebas para reducers?

El primer paso es organizar los archivos de test. Dentro de la carpeta test se crea una subcarpeta llamada reducers, y dentro de ella un archivo reducers.test.js [0:10]. Esta estructura mantiene el proyecto ordenado y facilita la localización de cada prueba.

Dentro del archivo se importan dos elementos esenciales:

  • El reducer que se usa en el proyecto, importado desde la carpeta reducers.
  • El productMock, un objeto simulado que representa un producto, importado desde la carpeta mocks.

Con estos dos elementos disponibles, se define la suite de pruebas utilizando describe, que agrupa todos los tests relacionados con el reducer [0:40].

¿Cómo se prueba que el reducer retorna el estado inicial?

La primera prueba verifica que el reducer retorna el estado inicial sin modificaciones cuando no coincide ninguna acción conocida [1:05]. Se construye de la siguiente manera:

javascript it('Retornar Initial State', () => { expect(reducer({}, '')).toEqual({}); });

Aquí se le pasa un objeto vacío como estado y un string vacío como acción. Dado que el reducer no encuentra coincidencia con ningún caso del switch (como addToCart o removeToCart), ejecuta el caso default y retorna el estado tal cual lo recibió [1:30].

El método toEqual compara estructuralmente ambos objetos. Si se cambia el valor esperado por un string vacío en lugar de un objeto vacío, la prueba falla porque los tipos no coinciden [2:15]. Esto demuestra que la comparación es estricta.

¿Qué pasa cuando hay errores de escritura en las pruebas?

Durante la ejecución aparecieron typos como escribir mal describe o reducer [2:00]. Es algo completamente normal y no debe generar frustración. El propio entorno de pruebas y JavaScript ayudan a detectar estos detalles rápidamente mostrando mensajes como reducer is not defined.

¿Cómo se prueba la acción addToCart en el reducer?

La segunda prueba valida que al despachar la acción addToCart, el producto se agrega correctamente al carrito [2:50]. Se construyen cuatro elementos clave:

  • initialState: un objeto con la propiedad cart como arreglo vacío.
  • payload: el productMock que simula el producto a agregar.
  • action: un objeto con type: 'addToCart' y el payload correspondiente.
  • expected: el resultado esperado, donde cart contiene el productMock.

javascript it('addToCart', () => { const initialState = { cart: [] }; const payload = productMock; const action = { type: 'addToCart', payload }; const expected = { cart: [productMock] };

expect(reducer(initialState, action)).toEqual(expected); });

El reducer recibe el estado inicial y la acción, entra al caso addToCart del switch y retorna un nuevo estado con el producto dentro del arreglo cart [3:30]. La aserción con toEqual confirma que el resultado coincide exactamente con lo esperado.

¿Por qué es importante definir bien cada variable?

Separar initialState, payload, action y expected en constantes independientes hace que la prueba sea legible y mantenible. Si el reducer cambia su lógica, solo hay que ajustar el valor esperado sin reescribir toda la prueba [3:50].

Al ejecutar todas las pruebas del proyecto se puede verificar que pasan correctamente los tests de actions, footer, product, reducers y header [4:30]. Cada componente y cada pieza de lógica queda cubierta por su respectiva prueba unitaria.

Si te han surgido dudas sobre cómo manejar los mocks o cómo estructurar pruebas más complejas, comparte tu experiencia en los comentarios.