Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. React

Probando componentes en React usando Jest y Enzima

by
Length:MediumLanguages:

Spanish (Español) translation by Steven (you can also view the original English article)

Esta es la segunda parte de la serie sobre las pruebas de componentes en React. Si tienes experiencia previa con Jest, puedes omitirla y usar el código de GitHub como punto de partida.

En el artículo anterior, cubrimos los principios básicos y las ideas detrás del desarrollo basado en pruebas. También configuramos el entorno y las herramientas necesarias para ejecutar pruebas en React. El conjunto de herramientas incluía Jest, ReactTestUtils, Enzyme y react-test-renderer.

Luego escribimos un par de pruebas para una aplicación demo usando ReactTestUtils y descubrimos sus deficiencias en comparación con una librería más robusta como Enzyme.

En este post, obtendremos una comprensión más profunda de las pruebas de los componentes en React escribiendo pruebas más prácticas y realistas. Puedes dirigirte a GitHub y clonar mi repositorio antes de empezar.

Introducción a la API de Enzyme

Enzyme.js es una librería de código abierto mantenida por Airbnb, y es un gran recurso para los desarrolladores de React. Utiliza la API ReactTestUtils por debajo, pero a diferencia de ReactTestUtils, Enzyme ofrece una API de alto nivel y una sintaxis fácil de entender. Instala Enzyme si aún no lo has hecho.

La API de Enzyme exporta tres tipos de opciones de representación:

  1. renderizado superficial
  2. renderizado DOM completo
  3. renderizado estático

El renderizado superficial se utiliza para representar un componente determinado de forma aislada. Los componentes secundarios no se representarán y, por lo tanto, no podrás afirmar su comportamiento. Si vas a concentrarte en las pruebas unitarias, te encantará esto. Puedes renderizar un componente de forma superficial de la siguiente manera:

La renderización completa de DOM genera un DOM virtual del componente con la ayuda de una librería denominada jsdom. Puedes utilizar esta función reemplazando el método shallow() por mount() en el ejemplo anterior. El beneficio obvio es que también puedes representar los componentes secundarios. Si deseas probar el comportamiento de un componente con sus elementos secundarios, debes usarlo.

La renderización estática se utiliza para representar componentes de react a HTML estático. Se implementa usando una librería llamada Cheerio, y puedes leer más sobre él en la documentación.

Revisitando nuestras pruebas anteriores

Estas son las pruebas que escribimos en el último tutorial:

src/components/__tests__/ProductHeader.test.js

La primera prueba verifica si el componente ProducerHeader tiene una etiqueta <h2>, y la segunda encuentra si tiene una clase CSS denominada title. El código es difícil de leer y entender.

Estas son las pruebas reescritas con Enzyme.

src/components/__tests__/ProductHeader.test.js

En primer lugar, creé un DOM de renderización superficial del componente <ProductHeader/> usando shallow() y lo almacené en una variable. Entonces, utilicé el método .find() para encontrar un nodo con la etiqueta 'h2'. Consulta el DOM para ver si hay una coincidencia. Puesto que solo hay una instancia del nodo, podemos asumir con seguridad que node.length será igual a 1.

La segunda prueba es muy similar a la primera. El método hasClass('title') devuelve si el nodo actual tiene un prop className con el valor 'title'. Podemos verificar esto mediante toBeTruthy().

Ejecuta las pruebas mediante yarn test, y ambas pruebas deben pasar.

¡Bien hecho! Ahora es el momento de refactorizar el código. Esto es importante desde la perspectiva de un tester porque las pruebas legibles son más fáciles de mantener. En las pruebas anteriores, las dos primeras líneas son idénticas para ambas pruebas. Puedes refactorizarlos utilizando una función beforeEach(). Como su nombre indica, se llama a la función beforeEach una vez antes de ejecutar cada especificación de un bloque.

Puedes pasar una función de flecha a beforeEach() como esta.

src/components/__tests__/ProductHeader.test.js

Escribir pruebas unitarias con Jest y Enzyme

Vamos a escribir algunas pruebas unitarias para el componente ProductDetails. Es un componente de presentación que muestra los detalles de cada producto individual.

Testing Components in React - ProductDetails component highlighted
Vamos a probar la sección que se resalta

La prueba unitaria intentará afirmar los siguientes supuestos:

  • El componente existe y los props se están pasando.
  • Se muestran los props como el nombre, la descripción y la disponibilidad del producto.
  • Se muestra un mensaje de error cuando los props están vacíos.

Aquí está la estructura de 'puros huesos' de la prueba. El primer beforeEach() almacena los datos del producto en una variable y el segundo monta el componente.

src/components/__tests__/ProductDetails.test.js

La primera prueba es fácil:

Aquí usamos el método props() que es útil para obtener los props de un componente.

Para la segunda prueba, puedes consultar elementos por sus nombres de clase y, a continuación, comprobar si el nombre del producto, la descripción, etc. forman parte de innerText de ese elemento.

El método text() es particularmente útil en este caso para obtener el texto interno de un elemento. Intenta escribir una expectativa para product.status() y mira si todas las pruebas están pasando.

Para la prueba final, vamos a montar el componente ProductDetails sin ningún prop. A continuación, vamos a buscar una clase llamada '.product-error' y comprobar si contiene el texto "Lo siento, el producto no existe".

Eso es todo. Hemos probado con éxito el componente <ProductDetails /> componente de forma aislada. Las pruebas de este tipo se conocen como pruebas unitarias.

Probando los callbacks con Stubs y Spies

Acabamos de aprender a probar props. Pero para probar realmente un componente de forma aislada, también debes probar las funciones callback (devolución de llamada). En esta sección, escribiremos pruebas para el componente ProductList y crearemos códigos auxiliares para las funciones callback en el camino. Estas son las suposiciones que debemos afirmar.

Testing components in React - ProductList Component
  1. El número de productos enumerados debe ser equivalente al número de objetos que el componente recibe como props.
  2. Al hacer clic en <a> debe invocar la función callback.

Vamos a crear una función beforeEach() que rellena los datos simulados del producto para nuestras pruebas.

src/components/__tests__/ProductList.test.js

Ahora, vamos a montar nuestro componente en otro bloque beforeEach().

ProductList recibe los datos del producto a través de props. Además de eso, recibe un callback del elemento primario. Aunque podrías escribir pruebas para la función callback del padre, no es una gran idea si tu objetivo es apegarte a las pruebas unitarias. Puesto que la función callback pertenece al componente primario, la incorporación de la lógica del elemento primario hará que las pruebas sean complicadas. En su lugar, vamos a crear una función stub.

¿Qué es un Stub?

Un stub es una función ficticia que pretende ser alguna otra función. Esto te permite probar de forma independiente un componente sin importar componentes primarios o secundarios. En el ejemplo anterior, creamos una función de tipo stub llamada handleProductClick invocando jest.fn().

Ahora sólo tenemos que encontrar todos los elementos <a> en el DOM y simular un clic en el primer nodo <a>. Después de hacer clic, comprobaremos si se ha invocado la función handleProductClick(). En caso afirmativo, es justo decir que nuestra lógica está funcionando según lo esperado.

Enzyme te permite simular fácilmente acciones del usuario, como clics utilizando el método simulate(). Y handlerProductClick.mock.calls.length retorna el número de veces que se llamó a la función simulada. Esperamos que sea igual a 1.

La otra prueba es relativamente fácil. Puedes utilizar el método find() para obtener todos los nodos <a> del DOM. El número de nodos <a> debe ser igual a la longitud de la matriz productData que creamos anteriormente.

Probando el Estado, Enlace de ciclo de vida y Método del componente

A continuación, vamos a probar el componente ProductContainer. Tiene un estado, un enlace de ciclo de vida y un método de clase. Aquí están las aserciones que necesitan ser verificadas:

  1. componentDidMount se llama exactamente una vez.
  2. El estado del componente se rellena después de montar el componente.
  3. El método handleProductClick() debe actualizar el estado cuando se pasa un identificador de producto como argumento.

Para comprobar si componentDidMount fue llamado, vamos a espiarlo. A diferencia de un stub, un espía se utiliza cuando se necesita probar una función existente. Una vez establecido el espía, puedes escribir aserciones para confirmar si se llamó a la función.

Puedes espiar una función de la siguiente manera:

src/components/__tests__/ProductContainer.test.js

El primer parámetro de jest.spyOn es un objeto que define el prototipo de la clase que estamos espiando. El segundo es el nombre del método que queremos espiar.

Ahora renderiza el componente y crea una aserción para comprobar si se llamó al espía.

Para comprobar que el estado del componente se rellena después de montarlo, podemos usar el método state() de Enzyme para obtener todo en el estado.

El tercero es un poco complicado. Necesitamos comprobar que handleProductClick funciona según lo esperado. Si te diriges al código, verás que el método handleProductClick() toma un identificador de producto como entrada y, a continuación, actualiza this.state.selectedProduct con los detalles de ese producto.

Para probar esto, necesitamos invocar el método del componente, y en realidad puedes hacerlo llamando a component.instance().handleProductClick(). Pasaremos un id de un producto de muestra. En el ejemplo siguiente, usamos el identificador del primer producto. A continuación, podemos probar si el estado se actualizó para confirmar que la aserción es verdadera. Aquí está el código completo:

Hemos escrito 10 pruebas, y si todo va bien, esto es lo que deberías ver:

Final output with tests passing

Resumen

¡Ufff! Hemos cubierto casi todo lo que necesitas saber para comenzar con la escritura de pruebas en React usando Jest y Enzyme. Ahora podría ser un buen momento para dirigirte al sitio web de Enzyme para tener una mirada más profunda a su API.

¿Qué piensas sobre la escritura de pruebas en React? Me encantaría escucharlos en los comentarios.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.