GraphQL — Testeando nuestras definiciones de Object Types con Jest

Cómo utilizar Jest para implementar tests de Integridad en la definición de nuestros Object Types.

Dailos Rafael Díaz Lara
CanariasJS
Published in
6 min readSep 28, 2017

--

¿Cuántos tests debería haber en un conjunto de pruebas? Desafortunadamente, la métrica que usan muchos programadores es “Estos parecen suficientes”. Un conjunto de pruebas debería abarcar todo aquello que podría fallar. Los tests son insuficientes siempre y cuando haya condiciones que no han sido analizadas por dichos tests o cálculos que no han sido validados.

(Clean Code, Robert C. Martin)

Basándonos en esta premisa, cuando estamos creando una API con GraphQL, con el objeto de asegurar que los modelos definidos para dicha API no cambian, lo que provocaría posibles problemas en el código de nuestro backend, es importante definir un conjunto de tests de Integridad.

Sí, he dicho tests de Integridad y no de Integración. Esto se debe a que con estos tests, vamos a verificar que la definición de los Object Types que hemos definido, continúan constantes a lo largo de todo el ciclo de vida de desarrollo de nuestra aplicación.

Código base

Para exponer cómo implementar tests para una API con GraphQL, me gustaría resaltar dos puntos de partida:

  1. Todos los ejemplos que se muestran en este documento están basados en el lenguaje Javascript.
  2. Voy a usar Jest como framework de testing.

Después de esto, la configuración básica de mi prototipo de proyecto será la siguiente:

Además, la estructura del proyecto que voy a usar será la siguiente:

El código completo mostrado en los siguientes pasos está disponible en este repositorio de GitHub.

Echando un vistazo al código que vamos a testear

Como ya supondrás por la estructura de proyecto mostrada en la imagen anterior, estoy definiendo el modelo para un user el cual, estará compuesto por campos de diversos tipos como Strings, Booleans, Emails, Direcciones, etc.

Este es el código del archivo user.type.js.

Como podemos ver en el código anterior, hemos importado tres Object Types personalizados ( PhoneNumberType, EmailAddressType and TimestampType) que van a ser usados para definir el tipo en algunos campos de nuestra definición de user.

De este modo, el contenido del archivo phone.number.type.js es el siguiente:

En este código he definido un GraphQLObjectType y un GraphQLInputObjectType. Esto es así porque el primero será usado cuando ejecutemos consultas mientras que el segundo se emplea cuando recibimos datos de entrada en las mutaciones.

Finalmente, el contenido del archivo email.address.type.js será el siguiente:

En este caso sucede lo mismo que en el archivo phone.number.type.js, es decir, usaremos el ObjectType para consultas y el InputType para las mutaciones.

A testear

Después de haber revisado el código base que vamos a testear, llega el momento de arrancar nuestra herramienta de testing. Para hacer esto, tenemos que abrir una nueva terminal (estando dentro del directorio del proyecto) y ejecutaremos el siguiente comando:

npm test

Debido a que no hemos definido ningún test aún, recibiremos el siguiente resultado:

Genial, ahora vamos a crear los archivos de testing y lo vamos a hacer probando las definiciones de Object Type más sencillas, es decir, empezaremos con el archivo phone.number.type.js.

Para hacer esto, crearemos un nuevo fichero al que denominaremos phone.number.type.test.js y a continuación, introduciremos en su interior el siguiente código:

Empezamos importando los módulo de Jest y GraphQL por un lado, así como el Object Type que deseamos testear, por el otro.

Después de esto, hemos definido un bloque describe que contendrá todos los tests.

Dentro del bloque describe hemos definido dos tests diferentes. El primero está orientado a testear el objeto destinado a las consultas mientras que el segundo, se encargará de testear el objeto empleado para las mutaciones.

En ambos casos, vamos a aprovecharnos del método getFields() proporcionado por el propio objeto tipo (PhoneNumberType en este caso).

De este modo, una vez hemos almacenado todos los campos del Object Type dentro de la variable phoneNumberFields, seremos capaces de comprobar sus valores.

Para hacer esto, voy a usar dos de los matchers proporcionados por Jest.

Con el primero (toHaveProperty) vamos a comprobar que el Object Type contiene el campo en cuestión.

El segundo matcher (toMatchObject) nos permitirá comprobar si el tipo de dato del campo analizado es el que hemos definido en el modelo.

Finalmente, guardamos el contenido del archivo y a continuación, le echamos un vistazo a la terminal donde ejecutamos el entorno de testing. Deberíamos obtener un resultado similar a este:

Genial. Nuestros tests están hechos y están todos en verde.

De acuerdo, vamos a implementar ahora el archivo email.address.type.js.

Para hacer esto, vamos a repetir los mismo pasos que dimos cuando creamos el archivo email.address.type.test.js y a continuación implementaremos el siguiente código:

Como podemos apreciar, en este nuevo script he implementado los mismos procedimientos que para el archivo phone.number.type.js pero en esta ocasión, hemos estado trabajando con el objeto EmailAddressType.

Ahora guardamos el archivo y volvemos a la terminal donde se está ejecutando nuestro entorno de testing. Deberíamos obtener un resultado similar a este:

Testeando Object Types anidados

Hasta ahora, hemos implementado tests para verificar campos definidos con tipos especificos de GraphQL pero, ¿qué sucede con Object Types cuyos campos están definidos como otro Object Type? ¿Cómo podemos testearlos?

Para hacer esto, vamos a basarnos en la definición del objeto UserType donde los campos phoneNumber, emailAddress, lastLoginTimestamp, createdAt y updatedAt son de tipo otro Object Type (PhoneNumberType, EmailAddressType y TimestampType).

Para testear este objeto, vamos a crear un nuevo archivo al que denominaremos user.type.test.js e implementaremos en su interior el siguiente código:

Como podemos observar, no tenemos problemas para poder testar los Object Types que hemos importado.

Después de hacer esto, si guardamos el contenido del archivo y volvemos a comprobar la terminal donde estamos ejecutando el framework de testing, deberíamos de ser capaces de obtener un resultado similar a este:

Perfecto. Todos nuestros tests están en verde.

Comprobando que los tests funcionan correctamente

Para verificar que nuestro entorno de testing está funcionando correctamente, vamos a editar el archivo user.type.js y reemplazaremos el tipo de dato definido para el campo username de GrpahQLString a GrpahQLInt.

A continuación, guardamos el archivo que acabamos de modificar y volvemos a la terminal donde se está ejecutando nuestra herramienta de testing. Deberíamos obtener un resultado similar a este:

Listo. Como esperábamos, nuestro tests ha fallado porque la comparación de tipo de dato es incorrecta ya que los dos tipos no coinciden.

Conclusión

Con este último ejemplo podemos concluir que los tests de integridad son posibles en GraphQL y que éstos pueden ser incluidos en nuestra pila de tests.

De este modo, si a lo largo del desarrollo de nuestra API, alguno de los tipos de dato definidos en los múltiples Object Types que hemos creado se modifica, nuestros tests nos avisarán de ello.

Espero que este documento te haya sido útil. Si es así, por favor, dale un voto positivo y compártelo en tus redes sociales.

Si lo deseas, puedes encontrarme en Twitter y en Linkedin.

Gracias y saludos.

--

--

Dailos Rafael Díaz Lara
CanariasJS

Multiplatform Software Developer seeking for new challenges