Sé más de testing que ayer (Episodio 2: Testeando el DOM y con la asincronía hemos topao')
Tags: spanish, codenewbie, javascript, testing
Published: 2021-05-21 18:52:54

Si, como yo, eres desarrollador/a junior sin experiencia, tengo buenas noticias para ti: el mercado laboral para nosotras por fin se activa después de muchos meses de frustración y pocas oportunidades. Si, como yo, ya te habías dado cuenta, supongo que entenderás ese sentimiento de: ¿A dónde ha ido a parar todo el tiempo que yo tenía para leer y estudiar?

Y es que no es solo el tiempo que invertimos en hacer las pruebas/tests/entrevistas propias de los procesos de selección, es todo el tiempo a mayores que dedicas a desgastar el botón de actualizar del email y estar súper nerviosa por tu futuro inmediato (porque digan lo que digan todos nos ponemos un poco nerviosos en esos momentos, y ponerse nervioso también lleva su tiempo y ocupa su espacio en la vida).

¿Que todo esto que estoy diciendo parecen excusas para acabar diciendo que he dejado lo del testing? Correcto, pero no es el caso. ¿Que entonces para qué lo cuento? Pues porque hablo mucho y la síntesis no es lo mío y tal. 

Centrándome en lo que me ocupa, durante esta semana he estado afianzando las funciones mock y probando el testeo de DOM, que no hubiera imaginado yo que era la fiesta que ha resultado ser. No fue una decisión consciente, me puse un día a hacer tests, coincidió que uno afectaba al DOM, y me di cuenta de que no funcionaba tal y como yo esperaba, vamos, no funcionaba en absoluto. Decidida me fui a la documentación y me encontré con esta guía específica de "Manipulación del DOM": [https://jestjs.io/es-ES/docs/tutorial-jquery](https://jestjs.io/es-ES/docs/tutorial-jquery) , leyendo eso me quedó claro que tenía que hacer algo especial para testear manipulaciones del DOM, pero en el ejemplo se usaba jQuery y yo estaba trabajando en JS Vanilla; además yo quería entender el por qué de lo que estaba pasando, así que no demoré, me puse las gafas de persona lista que lee mucho y empecé a investigar.

**Asincronía**

Tengo la teoría de que en todas las profesiones hay una pared con la que te encuentras constantemente estés haciendo lo que estés haciendo, y también la sensación de que en desarrollo front una de esas paredes tiene que ser la asincronía. 

¿Y qué pinta ahora la asincronía aquí? Pues bien, como seguro sabrás el código JS es asíncrono (es decir, sus funciones no se ejecutan en completa correspondencia temporal), y esto genera que cuando el test llega a la función empiecen a producirse errores debido a que no es capaz de reconocer las referencias a elementos HTML que se va encontrando. Por poner un ejemplo claro y sencillo: si le hacemos un test con Jest a una función que en algún punto recoge el elemento con clase "input" en HTML y le añade contenido de esta forma:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4tyl1eb1ky0oyxsg502r.png)

Jest no ejecutará el test, ya que no será capaz de reconocer esa parte del DOM a la que estamos intentando acceder y dará un error.  Esto mismo pasará con cualquier propiedad que hayamos utilizado y que actúe leyendo o modificando algún elemento HTML, dará error y el test no se ejecutará.

A esto se le suma un tema importante para el testing de front que me encontré por el camino mientras buscaba desesperada soluciones a todos mis problemas, y es que en un vídeo de CodelyTV (que dejaré referenciado abajo y es súper recomendable si estás empezando como yo) nos explican la importancia de centrarse en testear como usuario y no como desarrollador, es decir, que a la fuerza tenemos que acceder al HTML en algún momento.

En ese mismo vídeo Nuria hace una aproximación magistral y súper amplia al testing con Jest y Testing Library en 17 minutos (lo he tenido que mirar varias veces porque no sé cómo se puede contar tanto en tan poco tiempo... me quedo anonadada). Testing Library es una librería complementaria a Jest que viene a resolver el problema que comentábamos antes y que, aunque yo creía que su uso estaba limitado a la existencia de algún framework, según he visto posteriormente se puede utilizar en JS Vanilla también (dejo abajo un repositorio de GitHub con un ejemplo detalladísimo de esto y varias referencias a artículos súper interesantes sobre el tema).

Así que sí, ahí estaba yo con un test súper sencillo generando cinco mil errores que no había visto nunca, y unas 20 pestañas de Chrome abiertas cada una con información distinta (pero en todos los casos muy confusa) a sumar a mi maraña mental. Estaba viviendo uno de esos momentos en los que te dices mentalmente: "Recoge tus cuchillos y vete, es imposible que salgas de esta" cuando de repente di con EL  artículo, una persona que hace un año explicó exactamente lo que yo necesitaba saber en el presente. Dejo a continuación el link al artículo que está rebien explicado y masticado [https://dev.to/ms314006/use-jest-write-unit-testing-for-dom-manipulation-3n6c](https://dev.to/ms314006/use-jest-write-unit-testing-for-dom-manipulation-3n6c) . Básicamente explica cómo debemos utilizar Jest (sin librerías adicionales) para testear funciones que manipulan el DOM en JS vanilla, vamos, que lo necesites cuando estás leyendo esto o no, si todavía no sabes de testing déjate ese artículo en marcadores que te va a venir bien.

Una vez superada la fase "ERRORES A LO LOCO" conseguí hacer mi primer test: "cuando le doy aquí tiene que aparecer esto". Estupendo. Funciona. 

**Funciones mockeadas**

Llega el momento de hacerle un test a un input con un evento de escucha, quiero testear si llama correctamente a la función handler. ¡Pues a buscar otra vez! Aunque esta vez la búsqueda fue mucho más acotada y rápido di con la solución que más se ajustaba a lo que necesitaba: las funciones mockeadas. Es cierto que en el episodio 1 de "Sé más de testing que ayer" ya comenté su existencia, pero la realidad es que no llegué a desarrollar su aplicación.  

Las funciones mockeadas son funciones "espía", ¿Qué quiere decir esto?, que son funciones que nos permite crear Jest y que nos "cuentan" el comportamiento que tendrá cualquier otra función en su lugar. Imaginemos que tenemos una función llamada scaleImage() que se activa con la modificación de un input de tipo range (el típico zoom) por parte del usuario, si queremos saber exactamente cómo se comportará esa función haremos un test con ese mismo input apuntando a una función mockeada (en el ejemplo inputSize cuando ocurra el evento "mousemove" disparará mockFn, nuestra función mockeada), que como es nuestra espía nos contará todo lo que ha ocurrido cuando se le ha llamado. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qpohndfvtefb816xp63h.png)

En el código de ejemplo añadimos una implementación a la función mockeada, es decir, le decimos qué queremos que haga cuando la disparemos. Como cualquier otra función, si no le indicamos el valor a devolver o no indicamos una implementación, devolverá undefined.

En esta página de la documentación de Jest están todos los métodos que podemos usar con las funciones mock (para "preguntarle" detalles de su comportamiento o establecer la implementación entre otros muchos): [https://jestjs.io/es-ES/docs/mock-function-api](https://jestjs.io/es-ES/docs/mock-function-api) 

Hasta aquí mi avance de esta semana con Jest, como siempre, cualquier feedback (si es con amor o gatos) es bien recibido :)

Recursos: 

- Repositorio GitHub sobre testing en JS Vanilla con Jest+Testing Library (las referencias que deja el autor también son de muchísima utilidad para el contexto): [https://github.com/thawkin3/dom-testing-demo](https://github.com/thawkin3/dom-testing-demo)
- Vídeo youtube Midudev de testing en React JS con Jest+Testing Library: [https://www.youtube.com/watch?v=KYjjtRgg_H0](https://www.youtube.com/watch?v=KYjjtRgg_H0)
- Vídeo CodelyTV: [https://www.youtube.com/watch?v=SH7JSlc36uA](https://www.youtube.com/watch?v=SH7JSlc36uA)