Cómo testear tu front-end sin sufrir, con Jest y Enzyme

Romina A.
Unagi
Published in
5 min readNov 26, 2021
Illustration by Victoria Chepkasova from Ouch!

¿Trabajaste con tests unitarios de Javascript para testear tu front-end? Son bastante novedosos, así que si no los conocías, te los presento de lo más simple a lo más complejo.

En este caso vamos a trabajar con React para crear nuestros componentes. Para los tests, utilizaremos Jest, un framework de testing de Javascript y Enzyme, una librería para complementar y facilitar el uso de Jest.

Testeando el estado básico de un componente

En principio te muestro el caso más simple. Imaginemos que tenemos un componente con un estado u otro dependiendo de alguna condición.

Header

Como vemos, tenemos dos casos posibles: si hay o no un usuario. Sigamos buenas prácticas y escribamos un test para cada uno.

Header tests

Simple: primero renderizamos nuestro componente utilizando el método shallow y lo almacenamos en una variable, pasándole el valor de la propiedad que va a hacer la diferencia dentro del mismo, luego agregamos los expect que nos indican si encontramos los elementos correspondientes. Con eso ya testeamos que nuestro componente funciona como esperamos.

Ahora subamos un escalón más y juguemos con eventos del DOM.

Testeando el manejo de eventos

A veces vamos a tener condiciones más complejas, como por ejemplo, algún valor que se actualice luego del manejo de un evento. Si hablamos de un simple click, tal vez nos baste con jugar con la función simulate que nos provee Enzyme. Pero en esta oportunidad te quiero mostrar algo más complejo, como el manejo de un mapa.

Utilicemos como ejemplo la API Google Maps React. Imaginemos que vamos a ejecutar una función, “onDragEnd” cada vez que se termina de arrastrar el mapa.

MapView
MapView tests

Con una línea tan sencilla como la número 16, podemos ejecutar la función “onDragEnd” del componente, sin necesidad de hacer magia tratando de simular el comportamiento completo del usuario (ya que confiamos en que la API funciona, pues no deberíamos testear funciones de APIs externas). Simplemente validamos que se llame a la función correspondiente luego del manejo del evento esperado. Podés adaptar esto a cualquier librería con la que trabajes, o para cualquier evento imposible de simular con un solo click. Lo único que hay que hacer es mirar en profundidad qué opciones ofrece la función “props” de un nodo. Generalmente, deberías encontrar todas las funciones con las que el componente trabaja y poder llamarlas como a cualquier función.

Ahora subamos un peldaño más y juguemos a ser Dios🙌.

Testando llamadas asincrónicas

¿Existe caso más común en un front-end que hacer una petición asincrónica a nuestro servidor? Suena complicado, pero es posible. Si no me creés, mirá este ejemplo utilizando axios con tus propios ojos:

Vamos a tener una llamada que contempla el caso exitoso y el caso de error.

StatusQuery

Cuando estamos trabajando con librerías externas, deberíamos mockear (interceptar) el llamado a la librería real, ya que estamos manejando datos de prueba y no nos interesa testear el comportamiento y respuesta real. Una buena práctica es solamente testear que el llamado a la librería se ejecute y se le pasen los parámetros correctos. También podemos simular el retorno de una respuesta, justamente lo que necesitamos en este caso. Veamos un ejemplo.

Vamos a hacer un mock de la implementación del llamado a axios.

Para simular ambos escenarios, Jest nos provee con la función mockImplementation.

StatusQuery tests

Acá hay muchas cuestiones a analizar. Como vemos, en nuestra línea 8 llamamos a jest.mock(‘axios’). Con esto evitamos que se realice realmente cualquier petición usando esta librería.

Luego, a cada función del encabezado de cada “it” le agregamos la palabra clave “async”.

Esto es necesario ya que estamos trabajando con llamados asincrónicos, con lo cual necesitamos esperar (¿prestaste atención a la línea con “await”?) a que se complete la petición para que podamos ver los cambios reflejados en nuestro componente. Si es la primera vez que ves esto, te dejo más información aquí.

Es por ello que también agregamos la función runAllPromises, que se encarga de resolver todas las promesas, en este caso las de axios.

Ahora veamos el cuerpo del test: como te spoileé más arriba, utilizamos una función de Jest:

Básicamente, reemplazamos el comportamiento de la función request de axios, pasándole la función de reemplazo como parámetro. Para simular el caso exitoso, utilizamos Promise.resolve() y es opcional pasarle un objeto que contenga la respuesta simulada. Probablemente vayas a necesitar definir una respuesta si el cambio que esperás testear depende del valor de retorno.

Para el caso de error, utilizamos Promise.reject(), que también acepta un parámetro como objeto de respuesta.

El resto es muy intuitivo: luego de hacer click en el botón que hace el llamado a la API, esperamos el retorno de la promesa con await. Una vez finalizada la espera, vamos a testear que se haya llamado a la librería con los parámetros correspondientes, como te contaba más arriba.

También es importantísimo actualizar nuestro componente con la función update, sino jamás veremos los cambios reflejados. Por último, vemos que el mensaje que se renderiza es el que le pasamos en la respuesta simulada. ¡Con eso ya tenemos un test completo y que cubre todos los casos!

¡Eso es todo! Espero que este artículo te haya servido y te animes a llenar tu aplicación de tests. Al principio puede parecer difícil, pero en realidad es sólo algo nuevo. Te lo propongo como desafío.

¿Los utilizabas? ¿Qué te parecen? ¡Te invito a dejar tu opinión en los comentarios!

Y date una vuelta por nuestras redes sociales si querés saber qué otras cosas interesantes hacemos: Website, Linkedin, Twitter.

--

--

Romina A.
Unagi
Writer for

Full-stack developer at Unagi. I write code as a profession and for fun (mainly for fun).