¿Qué es Wiremock?

Es un simulador de APIs basadas en HTTP, un servidor de mocks para los amigos.

 

Una de las ventajas más importantes que tiene wiremock es que su peso en memoria en ínfimo comparado con otros métodos (en SoapUI cada mock levantado consumía alrededor de 300mb para cada api que teníamos, esto hacía que cuando levantáramos la aplicación tuviésemos como 1gb de memoria solo en mocks, con wiremock los mocks pasaron a pesar 100mb todos juntos)

Si bien wiremock se puede configurar y usar en un proyecto java, nosotros vamos a ver el uso standalone configurandolo mediante el API JSON que provee. Para ello primero vamos a ver cómo levantar wiremock y configurarlo:

Para levantar una instancia de wiremock sugerimos utilizar docker y configurarlo usando docker-compose. Un ejemplo básico de configuración es el siguiente:

 

version: '3'
services:
wiremock:
container_name: "mock"
build: ./
command: --port 7070
ports:
- 7070:7070
volumes:
- ./stubs:/home/wiremock



Lo único que destacamos de esta configuración es el linkeo de los volumenes, dentro de la carpeta “stubs” deben encontrarse 2 directorios, ambos al mismo nivel:

mappings: Es el directorio donde estarán todos los archivos referidos a la configuración de los mocks, consisten en archivos JSON que contienen una serie de requests y responses.

__files: Es el directorio que contiene los archivos que van a usarse para ser servidos en el body de la response de nuestros mocks. Pueden servirse cómo archivos binarios (para mockear un pdf a descargar, por ejemplo) o como texto plano (por ejemplo, si se trata de body JSON o xml).

Para levantar el servidor, entonces simplemente debemos ejecutar el comando

docker-compose up



alternativamente podemos correr
 

docker-compose up -d



para levantar la instancia en segundo plano.

Cuando el servidor wiremock se ejecuta, 2 directorios son creados en donde este se encuentre. Estos directorios son “mappings” y “__files”
Para empezar a usarlo de esta forma lo único que tenemos que hacer es dejar un archivo JSON en la carpeta mappings con el siguiente formato:

 

{
"request": {
"method": "GET",
"url": "/api/mytest"
},
"response": {
"status": 200,
"body": "More content\n"
}
}

Una vez hecho esto y reiniciado el servidor (docker-compose restart) podemos por postman consumir el endpoint que definimos ahí: “localhost/api/mytest”, en el caso que nos equivoquemos al consumir el endpoint wiremock nos dará una respuesta con el endpoint más cercano.

Otra ventaja muy buena que nos brinda esta tecnología es que todos los JSON que tengamos en la capeta mappings van a ser tomados por wiremock, esto nos permite tener mayor organización para nuestros endpoint (algo útil que nosotros estamos haciendo es tener un JSON por cada api que querramos mockear, esto nos sirve a nosotros porque manejamos una arquitectura de microservicios y así nos resulta más sencillo identificar cada api)

Cuando nos suceda que 2 endpoints se sobreponen, es decir, que hay 2 endpoints que devuelven distintas cosas podemos establecer una prioridad para que tome los endpoints en cierto orden, esto se logra agregando una property “priority” al JSON mostrado anteriormente. Por ejemplo:

 

{
"priority": 1,
"request": {
"method": "GET",
"url": "/api/specific-resource"
},
"response": {
"status": 200
}
}



Otra gran utilidad que encontramos en Wiremock es la amplia customización que nos permite sobre la response, por ejemplo en el caso de que el body de la response sea kilométrico podemos utilizar la property “bodyFileName” que nos permitirá especificar un archivo que tengamos en nuestro directorio “__files” (se acuerdan que lo mencione antes no?) básicamente le podemos especificar un JSON, un .pdf o lo que se nos ocurra (100% garantizado que funciona con pdfs, JSONs y jpgs) este sería el ejemplo:

 

{
"request": {
"method": "GET",
"url": "/body-file"
},
"response": {
"status": 200,
"bodyFileName": "path/to/myfile.xml"
}
}



También tenemos la posibilidad de que nuestro mock devuelva respuestas dinámicas y no siempre la misma información estática. Wiremock nos permite extender plugins que personalicen el comportamiento del mock. Esto nos sirve cuando por ejemplo necesitamos que cada respuesta tenga un identificador único o que una parte de la respuesta reproduzca algún parámetro de la query.

Algunas de las extensiones que Wiremock nos permite utilizar son Handlebars y Apache Velocity. Veamos un ejemplo utilizando Handlebars:

 

{
"request": {
"method": "GET",
"url": "/api/handlebars"
},
"response": {
"status": 200,
"bodyFileName": "templateHandlebars.vm",
"transformers": ["response-template"]
}
}



Y dentro del archivo que especificamos en bodyFileName colocamos:

 

<html>
<body>
<p>La primer parte del path es: {{request.path.[0]}}. </p>
</body>
</html>



Con esto devolveremos una respuesta como esta cuando un cliente acceda a http://localhost:8080/api/handlebars


La primer parte del path es: api

Por último, entre las varias utilidades de Wiremock, otra que nos pareció realmente práctica es que tenemos la chance de variar el comportamiento en base a un determinado estado de la API que estemos mockeando, La mayoría de los servicios web tienden a tener algún estado, que cambia a medida que se interactúa con ellos. WireMock admite el estado a través de la noción de escenarios. Un escenario es esencialmente una máquina de estados cuyos estados pueden asignarse arbitrariamente.

Debajo un ejemplo de cómo definimos los distintos estados dentro del archivo JSON que hayamos colocado en la carpeta mappings,

Debemos partir siempre del escenario Started, luego definimos nuestro siguiente estado en:

"newScenarioState": "Sin documentos pendientes de firma"

 

 {
"priority": 1,
"scenarioName": "Documentos pendientes",
"requiredScenarioState": "Started",
"newScenarioState": "Sin documentos pendientes de firma",
"request": {
"method": "GET",
"urlPattern": "/documentos-digitales/creditos/([0-9]+)/pendientes-firma"
},
"response": {
"status": 200,
"bodyFileName": "documentosPendientesDeFirma.json",
"headers": {
"Content-Type": "application/json"
}
}
}



Luego partimos del escenario anterior el cual era "Sin documentos pendientes de firma" y volvemos al escenario Started.

 {
"priority": 2,
"scenarioName": "Documentos pendientes",
"requiredScenarioState": "Sin documentos pendientes de firma",
"newScenarioState": "Started",
"request": {
"method": "GET",
"urlPattern": "/documentos-digitales/creditos/([0-9]+)/pendientes-firma"
},
"response": {
"status": 200,
"bodyFileName": "sinDocumentosPendientesDeFirma.json",
"headers": {
"Content-Type": "application/json"
}
}
}

 

Te mostramos algunas de las tantas ventajas que nos trae el uso de WireMock pero aún hay muchas más que podés descubrir.

¿Qué esperas para comenzar a utilizarla? 

Mandanos tus sugerencias

Ayudanos con ideas para los artículos de este blog a contacto@somospnt.com

¡Seguínos en nuestras redes sociales para enterarte de los últimos posts!