Sé más de testing que ayer (Episodio 3: los matchers más guays de Jest)
Tags: spanish, codenewbie, javascript, testing
Published: 2021-09-01 17:27:55

Cuando decidí empezar a aprender a estudiar testing por mi cuenta tuve que pasar muy por encima algunas cosas para ser capaz de darle un "concepto general" a lo que estaba aprendiendo. Como creo que ya conté en anteriores episodios de "Sé más de testing que ayer" (muy Troy McLure me ha quedado), cuando por fin me hice una idea general y ya tenía la documentación más o menos ubicada (yo es que antes de que una documentación me sea útil necesito un proceso de adaptación) me puse a hacer testing de forma, se podría decir, obsesiva. 

Desde que supe montar mi primer test, empecé a incluir testing en las pruebas técnicas que hacía, y en mis ratos libres hice los tests de una buena parte del repositorio que uso para resolver retos de Hackerrank. A medida que avanzaba haciendo test a diferentes funciones y aplicaciones me daba cuenta que los matchers tienen mucho más protagonismo e importancia de la que yo me había imaginado en un principio.

Entiendo que es una evolución normal, pasar de creer que "toBe" vale para todo, a saber que hay ocasiones en el que no lo puedes usar, a darte cuenta de que sin variar y bucear un poco en los matchers existentes no vas a poder sacarle el máximo partido a Jest, pero a mí me lo tuvieron que contar, la verdad.

Han pasado aproximadamente tres meses de la última vez que escribí sobre mis avances con los test unitarios en Jest y creo que ha llegado el momento de recopilar los matchers que me resultan más guays y útiles. Jest y yo hemos pasado por mucho juntos y nos lo merecemos. 

Matchers básicos: Para una función básica donde tengamos unos parámetros, una operación y un return, usaremos estos matchers. Es una forma de decir “espero que si le mando estos datos a esta función me devuelva esto otro”. Como veremos a continuación, dependiendo del tipo de dato que devuelva la función podremos usar uno u otro:

- toBe: comprueba una igualdad entre strings o números ( expect(2+2).toBe(4);). Se puede utilizar not.toBe si queremos negar una igualdad.
    ![toBe example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2pl11z3ena9o6q7y11oq.PNG)

![toBe example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ecxiewyzbnmy785cuzs5.PNG)    

- Con array y objetos sólo devolverá true cuando lo comparemos consigo mismo, en caso contrario aunque todas las propiedades sean iguales devolverá false.


![toBe array example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ic31xjacizwolclaau6.PNG)

- toEqual: Es el matcher adecuado para comprobar la igualdad en un objeto o array utilizaremos toEqual, ya que verificará y comparara los campos uno a uno. Podremos utilizar not.toEqual si queremos negar la igualdad.

![toEqual example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uy4tnvyex3sm5evo0usd.PNG)

Pues con esos dos matchers era que yo resolvía todos los problemas de testing que me iban surgiendo, hasta que un día una idea llegó a mí: “cuanta más información de lo que estás probando le des tú a Jest, más información te va a devolver él en caso de fallo”. Y ojo esto es importante, porque en cuanto empiezas a testear proyectos más grandes con funciones más diversas te das cuenta de que, o construyes una relación de respeto con Jest, o te va a amargar la existencia día a día y sin ningún remordimiento. 

Total, que hay momentos en los que dices “si es que yo no quiero comparar lo que devuelve esto, yo solo quiero saber que devuelve algo, o que no”. Pues claro, y muy lógico, y para eso hay un puñado de matchers que se denominan “de veracidad” y que se encargan de verificar a null, undefined, truthy o falsy. De este modo, si como veíamos en los primeros ejemplos, quisiéramos testear que una función devuelve algo simplemente podremos usar .not.toBeUndefined(), por ejemplo.

![veracity matchers](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qlg2qeru6qc6zgqtj9aq.PNG)

Del mismo modo podríamos validar si una función ha sido llamada con .toHaveBeenCalled();

Por otro lado, en lo referente a los números, aunque lo más habitual será usar el toBe o toEqual del principio, puede que yo tenga una función que genera números aleatorios del 1 al 10, y que quiera verificar que el resultado siempre está por debajo de 10 y por encima de 1, pues bien en ese caso tenemos un grupete de matchers que nos pueden ayudar como .toBeGreaterThanOrEqual() y .toBeLessThanOrEqual().

![comparative matchers](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hs90lc5bojos66gpbtfn.PNG)

Y también nos ocurrirá que tengamos que comprobar si un objeto o array tiene cierta propiedad o valor, pero no queramos comprobar la igualdad del array completo como haríamos con .toEqual(). Para esto podremos usar .toContain() (para valores en caso de arrays), .toMatchObject()(para clave-valor en caso de objetos), o .toHaveProperty() en el caso de que queramos verificar si existe una propiedad, independientemente de su valor.  

![partial equality](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y9xoi75bxm3eltpe1srf.PNG)

Del mismo modo, podríamos corroborar si algo es instancia de una clase con .toBeInstanceOf().

![classes matchers](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/255is8dy9vp4nz4n519u.PNG)

En cuanto a los strings, podremos usar .toMatch() para verificar una igualdad parcial o incluso una expresión Regex (de las cuales por cierto me está llegando ya la hora de aprender algo y son firmes voluntarias para aparecer en un post próximamente).

![regex and partial equality in strings](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/047nnwmttd2s20lzev55.PNG)

Por último, habrá ocasiones en las que tengamos que trabajar con una excepción, ya que el test cubre algún caso en el que se genera un error y lo queremos testear también. En estas ocasiones usaremos .toThrow(), o .toThrowError() si queremos validar el mensaje concreto que devolverá la excepción. Al respecto de estos dos matchers es importante indicar que el código de prueba deberá estar metido en una función, de lo contrario el test fallará y no llegará a validar el error. Esto lo podremos hacer creando una función y utilizándola luego en el expect, o introducir el código directamente en una arrow function dentro del expect.

![throw matchers](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v483zpexj56wiszjo7o2.PNG)

Como esto es lo típico que leerlo muy bien pero luego no te acuerdas y cuando lo necesitas tienes que volverlo a mirar todo desde cero… (y como soy una gran amante de las cheat sheets) dejo a continuación un esquemita resumen así como de mi cosecha por si a alguien le fuera remotamente útil :)

![cheatsheet](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uwqdr2ah2saipku1k34e.png)

Como siempre, cualquier comentario, si es con amor o gatos, es bien recibido.