Lecciones del curso

Testing en React con Jest y testing-library

Instalando Jest en nuestro proyecto
20m
Básicos de Jest
Matchers segunda parte
Números
Arrays
Async
Mocks primera parte
Mocks segunda parte
Mocks tercera parte
Testing sexta parte
Testing séptima parte
Matchers primera parte
Testing en Create React app
Explorando react-testing-library
Explorando testing-library/jest-dom
Detonando eventos con testing-library
Testing con snapshots
11m
Explorando el proyecto
Testeando nuestro primer componente con redux parte 1
Testeando nuestro primer componente con redux parte 2
Testing de actions creators y thunks (acciones asíncronas)
Testing reducers
Mock Avanzado: Peticiones http con msw.js
21m
Mock axios
Router primera parte
Router segunda parte
Router tercera parte
Router cuarta parte

Testeando nuestro primer componente con redux parte 1

Siguiendo con los temas del curso, en esta lección nos centraremos en seguir preparando nuestro entorno para poder empezar a con las pruebas en nuestra aplicación con redux.

Trabajaremos en el archivo App.test.js, para darnos una idea de qué es lo que necesitamos, en este archivo vamos crear una prueba donde intentaremos hacer el render de nuestro componente App.

// App.test.js import React from 'react'; import { render } from '@testing-library/react'; import App from '../App'; describe('<App /> component', () => { test('Render correctly', () => { const component = render(<App />) }); }

Este test funcionaría en caso de tener un componente simple, sin embargo, nuestro componente usa Redux, lo que significa que debemos crear un entorno donde le proporcionemos un lo necesario al componente, en este caso, el Provider.

Para esto, crearemos una carpeta llamada jest dentro de la carpeta raíz del proyecto y dentro de ella un archivo utils.js, es importante aclarar que este archivo solamente contiene utils de los tests.

. └── src / └── jest/ └── utils.js

Dentro de este archivo, escribiremos un componente que se va a encargar de montar nuestros componentes dentro de un Provider.

// App.test.js import React from "react"; import { render } from "@testing-library/react"; import { Provider } from "react-redux"; export const renderWithProvider = (component, { store, ...renderOptions }) => { return render(<Provider store={store}>{component}</Provider>, { ...renderOptions, }); };

Hacemos la importaciones necesarias y escribimos el utilitario, recibirá 2 parametros, el componente y un objeto { store, ...renderOptions }, lo importante de este objeto es el store, ya que ahí es donde tendremos la información que nuestro componente va a usar.

Ahora haremos los cambios pertinentes en el archivo App.test.js.

// App.test.js import React from 'react'; import { renderWithProvider } from '../jest/utils'; // cambiamos la importación import App from '../App'; describe('<App /> component', () => { test('Render correctly', () => { const component = renderWithProvider(<App />) // cambiamos el método }); }

Instalando redux-mock-store

Ahora solamente hace falta agregar el store con la información necesaria, para este propósito usaremos una librería que nos permite hacer un mock del store, el nombre del paquete es redux-mock-store.

$ npm install redux-mock-store --save-dev $ yarn add redux-mock-store --dev

La ventaja de usar este paquete es que permite manejar y crear un store a partir de información que nosotros queramos, además de permitirnos detectar cuántas y cuaáles son las acciones que se despacharon en la aplicación.

Para usarlo es necesario hacer la importación y después crearemos una constante mockStore que contenga el resultado de ejecutar el módulo y dentro de nuestra prueba crearemos una constante llamada store y es ahí mismo donde agregaremos la información que nuestro componente necesita o dicho en otras palabras el initialState de nuestro componente:

// App.test.js import React from "react"; import { renderWithProvider } from "../jest/utils"; import App from "../App"; import createMockStore from "redux-mock-store"; const mockStore = createMockStore(); // ejecutamos el módulo describe('<App /> component', () => { test('Render correctly', () => { const store = mockStore({ products: { data: [] }, cart: { data:[] }}) // creamos el store y agregamos data const component = renderWithProvider(<App />, { store }); // agregamos el store }); }

Ahora al correr los tests podremos observar que el error que veíamos anteriormente ya no aparece, sin embargo, nos enfrentamos a otro reto, el problema es que ahora tenemos un error en el dispatch.

// App.js useEffect(() => { if (status === "") dispatch(getProducts()); if (status === "") dispatch(getCart()); }, [dispatch]);

La razón es que a pesar de tener configurado el provider, estamos usando acciones asíncronas, especificamente, thunk lo que significa es debemos darle la posibilidad a nuestro entorno de manejar este tipo de acciones, lo que haremos es importar el middleware de redux-thunk y pasarlo dentro de un arreglo al módulo createMockStore.

// App.test.js import React from "react"; import { renderWithProvider } from "../jest/utils"; import App from "../App"; import createMockStore from "redux-mock-store"; import thunk from "redux-thunk"; // importamos redux-thunk const mockStore = createMockStore([thunk]); // pasamos el arreglo de middlewares describe('<App /> component', () => { test('Render correctly', () => { const store = mockStore({ products: { data: [] }, cart: { data:[] }}) const component = renderWithProvider(<App />, { store }); }); }

En este caso solamente usamos thunk sin embargo si nuestra aplicación usara más middlewares basta con agregarlos a este arreglo y listo.

Código completo

// App.test.js import React from "react"; import { renderWithProvider } from "../jest/utils"; import App from "../App"; import createMockStore from "redux-mock-store"; import thunk from "redux-thunk"; const mockStore = createMockStore([thunk]); describe('<App /> component', () => { test('Render correctly', () => { const store = mockStore({ products: { data: [] }, cart: { data:[] }}) const component = renderWithProvider(<App />, { store }); }); }
spaceman

¿List@ para ver todo el curso? Prepárate porque apenas estamos comenzando 🚀

¡Desbloquea el curso completo y conviértete en un PRO del desarrollo web! 🫶🏻 .