Integrar Jest con Enzyme en un proyecto React (Create React App)

Este artículo esta basado en https://blog.usejournal.com/testing-with-jest-and-enzyme-in-react-part-1-162ce7466128

ReactJS es una librería Javascript diseñada para la creación de Interfaces web, es mantenida por Facebook y ampliamente utilizada en la actualidad.

Jest

Jest es un framework creado para realizar Pruebas Unitarias (Unit Testing) enfocado en la simplicidad y la velocidad. Algunas de sus características principales son:

• Permite la ejecución de pruebas en paralelo para maximizar el rendimiento.
• Es una librería de aserciones (assertion library).
• Permite la construcción de mocks de manera similar a Sinon JS.
• Ofrece la posibilidad de crear informes de cobertura.
• Fácil de configurar.

Enzyme

Enzyme es una utilidad diseñada para React JS con el fin de facilitar la creación de pruebas para los Componentes hechos en React

Comenzando con Jest

  1. Crear una aplicación utilizando create-react-app

Antes de empezar con a integrar Jest en nuestro proyecto primero debemos crearlo, para esto usaremos la herramienta create-react-app

npx create-react-app react-jest-app
cd react-jest-app
npm start 

Nota: npx es una utilidad creada para ejecutar paquetes localmente o en este caso ejecutar paquetes sin necesidad de instalarlos globalmente.

La estructura del proyecto debe lucir como se muestra a continuación:

2. Ejecutando una prueba de demostración con Jest

• Primero debemos borrar el archivo App.test.js que viene por defecto.
• Instalamos Jest como dependencia de desarrollo.

npm install --save-dev jest

• Modificamos en nuestro package.json el script test con el valor jest.

{
  "name": "react-jest-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.3.2",
    "@testing-library/user-event": "^7.1.2",
    "react": "^16.13.0",
    "react-dom": "^16.13.0",
    "react-scripts": "3.4.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "jest",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
  "devDependencies": {
    "jest": "^25.1.0"
  }
}

• Creamos una carpeta test en la raíz del proyecto.
• Dentro de /test agregamos un nuevo archivo demo.test.js con el siguiente contenido:

it("suma correctamente", () => {
  expect(1+1).toEqual(2);
});

• Nuestro proyecto debe lucir de la siguiente manera:

• Abrimos un terminal y ejecutamos el siguiente comando

npm test

• Deberíamos ver el siguiente resultado

Explicación

• Cuando ejecutamos el comando npm test automáticamente se ejecuta Jest con las configuraciones por defecto.
• Por defecto Jest busca todos los archivos que con extensión .test.js y los identifica como archivos con pruebas unitarias.
• En la prueba estamos esperando que las suma de 1 + 1 sea igual a 2.

3. Instalando Enzyme

• Instalamos la librería Enzyme y el adaptador acorde a nuestra versión de React, en mi caso estamos usando react 16.13 por lo que necesitamos enzyme-adapter-react-16

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

4. Instalando babel-preset-env

babel-preset-env permite utilizar las nuevas características de ES6 en nuestras pruebas.

Ahora nuestro package.json se ve así:

{
  "name": "react-jest-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.3.2",
    "@testing-library/user-event": "^7.1.2",
    "react": "^16.13.0",
    "react-dom": "^16.13.0",
    "react-scripts": "3.4.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "jest",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "babel-preset-env": "^1.7.0",
    "enzyme": "^3.11.0",
    "enzyme-adapter-react-16": "^1.15.2",
    "jest": "^25.1.0"
  }
}

5. Configuración de Babel

Vamos a crear un archivo .babelrc en la raíz del proyecto con el siguiente contenido:

{
  "presets": [
    "@babel/preset-env",
    "react-app"
  ]
}

Nota: Los presets react-app ya vienen incluidos al momento de crear el proyecto con create-react-app por lo que no es necesario instalarlos de nuevo (https://www.npmjs.com/package/babel-preset-react-app#usage-in-create-react-app-projects)

6. Configuración para Jest

• Dentro de la carpeta /test vamos a crear un archivo setupTests.js con el siguiente contenido:

import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';;

// React 16 Enzyme adapter
Enzyme.configure({ adapter: new Adapter() });

• Agregamos una configuración adicional en nuestro package.json apuntando al archivo de configuración

...
  "jest": {
    "setupFilesAfterEnv": [
      "./test/setupTests.js"
    ]
  }
...

• Ahora nuestro package.json se ve así

{
  "name": "react-jest-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.3.2",
    "@testing-library/user-event": "^7.1.2",
    "react": "^16.13.0",
    "react-dom": "^16.13.0",
    "react-scripts": "3.4.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "jest",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "babel-preset-env": "^1.7.0",
    "enzyme": "^3.11.0",
    "enzyme-adapter-react-16": "^1.15.2",
    "jest": "^25.1.0"
  },
  "jest": {
    "setupFilesAfterEnv": [
      "./test/setupTests.js"
    ]
  }
}

7. Crear un componente de prueba

• Dentro de la carpeta /src vamos a crear una nueva carpeta llamada components.
• Dentro de /src/components crearemos una carpeta Title y dentro de esta un index.js con el siguiente contenido:

import React from 'react';

const Title = ({ children }) => (
  <h1>{children}</h1>
);

export default Title;

8. Escribir una prueba con Jest y Enzyme

• Dentro de la carpeta /test vamos a crear un nuevo archivo Title.test.js con el siguiente contenido:

import React from 'react';
import { shallow } from 'enzyme';
import Title from '../src/components/Title';
const title = 'Test Title';
let wrapped = shallow(
  <Title>{title}</Title>
);
describe('Title', () => {
  it('renders the Titles children', () => {
    expect(wrapped.find('h1').text()).toEqual(title);
  });
});

• En esta prueba estamos validando que el texto que se presenta dentro de la etiqueta <h1> del componente Test coincida con el contenido que esta siendo agregado como hijo al momento de utilizar el componente.

Ahora la estructura de nuestro proyecto luce así:

• En un terminal solo nos queda ejecutar npm test

Código en Github: https://github.com/JhymerMartinez/react-jest-app