Jest — “Manual Mocking” con módulos propios, fuera del archivo de testing.

Dailos Rafael Díaz Lara
CanariasJS
5 min readAug 12, 2017

--

Una de las principales características que diferencia a Jest de otros frameworks de testing es su capacidad para simular o “hacer mocking” sobre las dependencias de los módulos que desarrollamos o empleamos en nuestras aplicaciones.

El principal beneficio que proporciona esta técnica y que forma parte de la filosofía de Jest es que, cuando implementamos los tests de un determinado módulo, este debe probarse de manera totalmente aislada del resto de dependencias que se hayan definido para su correcto funcionamiento. Dicho aislamiento lo conseguimos simulando la respuesta de estas dependencias.

Originalmente, esta funcionalidad venía activada por defecto de manera que, cualquier dependencia en nuestros módulos, en el momento de definir nuestros archivos de test, estaba “mockeada”.

El equipo de desarrollo de Jest se dio cuenta de que cuando se intentaba aplicar este nuevo framework sobre un proyecto ya existente, se consumían muchos recursos de procesamiento y la ejecución de los tests se ralentizaba considerablemente, ya que Jest debía revisar todo el proyecto y simular todas las dependencias.

Es por esta razón por lo que en las últimas versiones de Jest, el “mocking” automático viene desactivado por defecto (pudiendo activarlo a través de las opciones de configuración proporcionadas por el propio framework), de ahí que, si queremos simular cualquier módulo, debamos hacerlo a mano mediante lo que en Jest denominan “manual mocking”.

Punto de partida

Para ver cómo podemos implementar el manual mocking, partiremos de un proyecto de ejemplo basado en NodeJS, cuya estructura será la siguiente:

La configuración de este proyecto viene dada por el archivo package.json.

Como se puede apreciar en la imagen anterior, el núcleo de nuestro proyecto se encuentra contenido en el directorio src. Aquí podemos encontrar el directorio utils donde hemos definido un módulo a cuyo archivo hemos denominado calculator.js y su contenido es el siguiente:

En este módulo se definen dos funciones que realizarán la suma y la resta de dos valores que pasemos por parámetros.

Continuando dentro del directorio utils, encontramos el subdirectorio __mocks__ en cuyo interior encontramos el archivo calculator.mock.js que contendrá el código que simulará al modulo calculator, como veremos más adelante.

Además de esto, en el directorio src también podemos encontrar el archivo principal del proyecto al que hemos denominado app.js y que será sobre el cual ejecutaremos los tests.

Como podemos apreciar, estamos importando el módulo calculator y hemos definido las funciones doASum y doADif en cuyo interior hemos definido dos valores fijos y como resultado, en cada una de las funciones devolvemos la llamada a los método proporcionados por el módulo del cual depende nuestra aplicación.

Comencemos a testear

En la raíz de nuestro proyecto hemos definido el directorio test y en su interior, está el archivo app.test.js que contiene el siguiente código:

En este caso, ninguna dependencia está simulada (mocked) por lo que si ejecutamos el test (npm test), el resultado que obtendremos será el siguiente:

Todo ha ido según lo esperado ya que al estar testeando el módulo app, por defecto, la dependencia con el módulo calculator se ha cargado directamente y el test ha pasado en verde.

Manual mocking time

Ahora vamos a ponernos en el caso de que el módulo calculator es mucho más complicado, tiene peticiones AJAX, realiza validaciones y comprobaciones complejas, albergará funcionalidades que aún no se van a desarrollar pero aún no están implementadas, etc.

Ante esta panorámica, nuestro módulo app sigue evolucionando y es necesario realizar los tests correspondientes.

Es en estos casos donde la simulación de dependencias hace acto de presencia.

Para ver cómo implementarla, lo que vamos a hacer es introducir el siguiente código en el archivo utils/__mocks__/calculator.mock.js:

De este script, lo primero en lo que debemos poner atención es el método jest.mock(). Éste será el responsable de “mockear” el módulo calculator.

En Jest, cuando simulamos un módulo, realmente lo que sucede es que se crea un objeto totalmente vacío. Es por esta razón por la cual, al “mockear” un módulo, también deberemos “mockear” aquellas funciones o métodos que deseemos utilizar en aquel código que dependa de este módulo.

Para simular una función en Jest, deberemos emplear el método jest.fn(). En esta ocasión, hemos simulado las funciones sum y dif forzándolas a devolver 20 y -20 respectivamente cuando sean utilizadas.

Haciendo uso del Manual Mocking

Ahora que nuestro mock está preparado, es el momento de usarlo. Para ello, editaremos el código de nuestro archivo app.test.js de manera que quede de la siguiente forma:

Una cosa que debemos tener en cuenta es el orden de carga de los módulos, es decir, cuando estemos simulando módulos, la importación de dichas simulaciones deberá hacerse en la parte superior del archivo de testing, lo más arriba posible, antes de cualquier otra dependencia.

Después de haber aclarado esto, en el script anterior podemos apreciar que hemos importado el módulo simulado calculator y a continuación, el módulo app.

De esta manera, cuando app cargue la dependencia de calculator, ahora no utilizará el módulo original que definimos sino el que hemos simulado.

Para verificar que esto es así, lo único que debemos hacer es ejecutar nuevamente el test y obtendremos el siguiente resultado:

Como podemos ver, en esta ocasión el test ha fallado porque, aunque esperábamos obtener el 15 hemos obtenido el valor 20.

No obstante, a pesar de que el test ha fallado, hemos verificado que el “manual mocking” sí ha funcionado correctamente ya que estamos recibiendo el valor que indicamos cuando mockeamos la función sum en el archivo calculator.mock.js.

Conclusión

Ya hemos visto cómo podemos crear simulaciones de dependencias en aquellos módulos que estemos testeando.

De este modo y a través de la inclusión de los mocks en nuestros tests, podemos centralizar los mocks de nuestro código en un único directorio o distribuirlos en los directorios de los componentes, dependiendo de cómo vayamos a estructurar nuestro proyecto.

Para concluir, a partir de ahora podremos probar nuestras nuevas funcionalidades sin el miedo a depender de módulos que posean a su vez dependencias o cuyos métodos aún no han sido implementados o testeados.

Recursos

  • Repositorio con los scripts mostrados en este artículo: link.
  • Página oficial de Jest: link.
  • Configuración adicional de Jest: link.

--

--

Dailos Rafael Díaz Lara
CanariasJS

Multiplatform Software Developer seeking for new challenges