Hacer test de componentes en React con Enzyme

  • Instalación de Enzyme en React
  • React 16
  • React 17
  • Snapshots
  • Configuración de Enzyme en React
  • Configuración de Enzyme para React 16
  • Configuración de Enzyme para React 17
  • Componente de ejemplo para los tests:
  • Tests que vamos a realizar sobre el componente
  • Testing
  • Importamos las dependencias
  • ¿Qué es describe?
  • Los tests, ¡por fin!
  • Test 1: debería mostrar correctamente
  • Test 2: debe de mostrar el valor por defecto de 100
  • Test 3: debe incrementar con el botón +1
  • Test 4: debe decrementar con el botón -1
  • Test 5: debe de colocar el valor por defecto con el botón reset
  • Resultado final de los tests
  • beforeEach
  • Conclusiones

Instalación de Enzyme en React

React 16

npm i --save-dev enzyme enzyme-adapter-react-16

React 17

npm i --save-dev enzyme
npm install --save-dev @wojtekmaj/enzyme-adapter-react-17

Snapshots

npm install --save-dev enzyme-to-json

Configuración de Enzyme en React

Configuración de Enzyme para React 16

import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import { createSerializer } from 'enzyme-to-json';
Enzyme.configure({ adapter: new Adapter() });
expect.addSnapshotSerializer(createSerializer({ mode: 'deep' }));

Configuración de Enzyme para React 17

import Enzyme from 'enzyme';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
import { createSerializer } from 'enzyme-to-json';
Enzyme.configure({ adapter: new Adapter() });
expect.addSnapshotSerializer(createSerializer({ mode: 'deep' }));

Componente de ejemplo para los tests:

  1. Botón para aumentar +1 el contador
  2. Botón para resetear el contador
  3. Botón para restar -1 el contador
import React, { useState } from 'react';export const CounterApp = ({ value = 10 }) => {
const [counter, setCounter] = useState(value);
const handleUp = () => setCounter((counterPref) => counterPref + 1);
const handleDown = () => setCounter((counterPref) => counterPref - 1);
const handleReset = () => setCounter(value);
return (
<>
<h1>Counter App</h1>
<div>
<h2>{counter}</h2>
<div>
<button onClick={handleUp}>+1</button>
<button onClick={handleReset}>Reset</button>
<button onClick={handleDown}>-1</button>
</div>
</div>
</>
);
};
<CounterApp value="{100}" />

Tests que vamos a realizar sobre el componente

  1. Se debería mostrar correctamente.
  2. Debe de mostrar el valor por defecto de 100
  3. Debe incrementar con el botón +1
  4. Debe decrementar con el botón -1
  5. Debe de colocar el valor por defecto con el botón reset

Testing

import '@testing-library/jest-dom';
import { shallow } from 'enzyme';
import { CounterApp } from '../CounterApp';
describe('Probamos el componente <CounterApp />', () => {
let wrapper = shallow(<CounterApp />);
beforeEach(() => {
wrapper = shallow(<CounterApp />);
});
test('debería mostrar <CounterApp /> correctamente ', () => {
expect(wrapper).toMatchSnapshot();
});
test('debe de mostrar el valor por defecto de 100', () => {
const wrapper = shallow(<CounterApp value={100} />);
const counterText = wrapper.find('h2').text().trim();
expect(counterText).toBe('100');
});
test('debe incrementar con el botón +1', () => {
wrapper.find('button').at(0).simulate('click');
const counterText = wrapper.find('h2').text().trim();
expect(counterText).toBe('11');
});
test('debe decrementar con el botón -1', () => {
wrapper.find('button').at(2).simulate('click');
const counterText = wrapper.find('h2').text().trim();
expect(counterText).toBe('9');
});
test('debe de colocar el valor por defecto con el botón reset', () => {
const wrapper = shallow(<CounterApp value={105} />);
wrapper.find('button').at(0).simulate('click');
wrapper.find('button').at(1).simulate('click');
const counterText = wrapper.find('h2').text().trim();
expect(counterText).toBe('105');
});
});

Importamos las dependencias

import '@testing-library/jest-dom';
import { shallow } from 'enzyme';
import { CounterApp } from '../CounterApp';
  • @testing-library/jest-dom dependencia no es obligatoria importarla, pero si recomendable porque así nos habilitará el IntelliSense para los tests, y esto es algo muy cómodo para no tener que ir recordando todos los nombres de las funciones y demás.
  • enzyme es la librería con el core de enzyme para los tests. Importación obligatoria.
  • CounterApp es nuestro componente con su ruta relativa que vamos a testear.

¿Qué es describe?

describe('Probamos el componente <CounterApp />', () => {
// Aquí dentro irán los tests para este grupo
});

Los tests, ¡por fin!

let wrapper = shallow(<CounterApp />);beforeEach(() => {
wrapper = shallow(<CounterApp />);
});

Test 1: debería mostrar correctamente

test('debería mostrar <CounterApp /> correctamente ', () => {
expect(wrapper).toMatchSnapshot();
});
// Jest Snapshot v1, https://goo.gl/fbAQLPexports[
`Probamos el componente <CounterApp /> debería mostrar <CounterApp /> correctamente 1`
] = `
<Fragment>
<h1>
Counter App
</h1>
<div>
<h2>
10
</h2>
<div>
<button
onClick={[Function]}
>
+1
</button>
<button
onClick={[Function]}
>
Reset
</button>
<button
onClick={[Function]}
>
-1
</button>
</div>
</div>
</Fragment>
`;

Test 2: debe de mostrar el valor por defecto de 100

test('debe de mostrar el valor por defecto de 100', () => {
const wrapper = shallow(<CounterApp value={100} />);
const counterText = wrapper.find('h2').text().trim();
expect(counterText).toBe('100');
});
const wrapper = shallow(<CounterApp value={100} />);let wrapper = shallow(<CounterApp />);
<h2>{counter}</h2>

Test 3: debe incrementar con el botón +1

test('debe incrementar con el botón +1', () => {
wrapper.find('button').at(0).simulate('click');
const counterText = wrapper.find('h2').text().trim();
expect(counterText).toBe('11');
});
<button onClick="{handleUp}">+1</button>
<button onClick="{handleReset}">Reset</button>
<button onClick="{handleDown}">-1</button>

Test 4: debe decrementar con el botón -1

test('debe decrementar con el botón -1', () => {
wrapper.find('button').at(2).simulate('click');
const counterText = wrapper.find('h2').text().trim();
expect(counterText).toBe('9');
});

Test 5: debe de colocar el valor por defecto con el botón reset

test('debe de colocar el valor por defecto con el botón reset', () => {
const wrapper = shallow(<CounterApp value={105} />);
wrapper.find('button').at(0).simulate('click');
wrapper.find('button').at(1).simulate('click');
const counterText = wrapper.find('h2').text().trim();
expect(counterText).toBe('105');
});

Resultado final de los tests

beforeEach

beforeEach(() => {
wrapper = shallow(<CounterApp />);
});

Conclusiones

--

--

alextomas.com

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store