Ir al contenido principal

Wiremock en un vistazo

Wiremock es una herramienta que nos permite crear entornos de prueba estables al simular el comportamiento de servicios web reales, aislarse de dependencias externas y simular APIs incluso antes de que estén construidas. Se le considera como un simulador de API HTTP o un servidor web HTTP Mock.

¿Qué tiene que ver con JUnit y/o Mockito?

  • JUnit sirve para orquestar y ejecutar las pruebas. 
  • Mockito se usa para simular objetos y dependencias internas del código que se está probando (pruebas unitarias). 
  • WireMock simula servicios externos como APIs HTTP (pruebas de integración).

Es común que trabajen en conjunto en diversos proyectos.

Wiremock nos permite:

  • La simulación de la herramienta de virtualización. 
  • Crear datos estáticos para pruebas unitarias. 
  • La simulación de respuestas HTTP fallidas. 
  • La simulación de tiempo de espera. 
  • La simulación de latencia. 
  • La simulación de respuestas HTTP para un servicio RESTful inexistente.

Un equipo desarrollador no necesitaría que otro equipo tenga las APIs listas para probar. Wiremock nos proporcionaría lo necesario para probar esas APIs inexistentes. Esto gracias a la simulación.

Veremos cómo ocuparlo. Crearemos unas pruebas mock para simular peticiones a un servicio que obtiene el Índice de Masa Corporal (IMC) de una persona, donde las entradas serán su peso y talla. No es necesario que ese servicio exista, pues con Wiremock simularemos su existencia.

1. Crear el proyecto Java con Maven:

$ mvn archetype:generate

2. Nos ubicamos en el directorio generado:

$ cd proyecto-maven

3. En el archivo ``pom.xml`` agregamos las dependencias necesarias:

<dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <scope>test</scope>
</dependency>
<dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-params</artifactId>
      <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.wiremock</groupId>
    <artifactId>wiremock</artifactId>
    <version>3.13.1</version> 
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.20.0</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.14</version>
</dependency>

Agregamos las dependencias de JUnit, Wiremock y HttpClient de Apache, pues estamos creando una aplicación HTTP.

4. Creamos la aplicación HTTP para el calculo del IMC.

Main.java

package com.inforhomex.app;

import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public class Main {
    public static void main(String[] args) {
        System.out.println("Hola, mundo!");
    }

     public double getIMC(double peso, double talla) {
        return peso / (talla * talla);
    }

    public String validarIMC(double imc) throws Exception {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpGet request = new HttpGet("http://localhost:8083/validar-imc?valor=" + imc);
    CloseableHttpResponse response = client.execute(request);
    
    int statusCode = response.getStatusLine().getStatusCode();
    if (statusCode != 200) {
        System.out.println("Error: HTTP Status " + statusCode);
        throw new RuntimeException("Unexpected HTTP status: " + statusCode);
    }
    
    String jsonResponse = EntityUtils.toString(response.getEntity());
    System.out.println("Response: " + jsonResponse); 
    ObjectMapper mapper = new ObjectMapper();
    JsonNode root = mapper.readTree(jsonResponse);
    return root.get("estado").asText();
}
}

5. Compilamos:

$ mvn clean compile

Si todo va bien, descargará las dependencias definidas en el XML.

6. Crear la clase con las pruebas mock.

MainTest.java

package com.inforhomex.app;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.Test;
import com.inforhomex.app.Main;

import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static org.junit.jupiter.api.Assertions.*;

public class MainTest {



    private WireMockServer wireMockServer;
    private Main calculadora;
    
    @BeforeEach
    void setUp() {
        wireMockServer = new WireMockServer(8083); 
        wireMockServer.start();
        WireMock.configureFor("localhost", 8083);
        calculadora = new Main();
    }
    
    @AfterEach
    void tearDown() {
        wireMockServer.stop();
    }
    
    @Test
    void testGetIMC() {
        double imc = calculadora.getIMC(70, 1.75);
        assertEquals(22.86, imc, 0.01);  
    }

    @Test
    void testValidarIMC_Normal() throws Exception {
    stubFor(get(urlPathEqualTo("/validar-imc"))
            .withQueryParam("valor", matching("22.85.*")) 
            .willReturn(aResponse()
                    .withStatus(200)
                    .withHeader("Content-Type", "application/json")
                    .withBody("{\"estado\": \"normal\"}")));
    
    double imc = calculadora.getIMC(70, 1.75);
    String resultado = calculadora.validarIMC(imc);
    assertEquals("normal", resultado);
}
    
    @Test
    void testValidarIMC_BajoPeso() throws Exception {
        
        stubFor(get(urlMatching("/validar-imc\\?valor=.*"))
                .withQueryParam("valor", matching("16.0"))
                .willReturn(aResponse()
                        .withStatus(200)
                        .withHeader("Content-Type", "application/json")
                        .withBody("{\"estado\": \"bajo peso\"}")));
        
        String resultado = calculadora.validarIMC(16.0);
        assertEquals("bajo peso", resultado);
    }

    

}

7. Ejecutar el test:

$ mvn test

Si todo va bien, veremos esto en consola:

[INFO]
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.inforhomex.app.MainTest
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Response: {"estado": "normal"}
Response: {"estado": "bajo peso"}
[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 6.988 s -- in com.inforhomex.app.MainTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  22.851 s
[INFO] Finished at: 2025-10-19T10:42:02-06:00
[INFO] ------------------------------------------------------------------------

Lo que podemos ver es:

  • @BeforeEach: Inicia el servidor WireMock en puerto 8083 y configura el cliente. 
  • @AfterEach: Detiene el servidor para limpiar. 
  • stubFor: Define el mock. Aquí, para GET a /validar-imc?valor=XX, retorna un JSON fijo basado en el parámetro. 
La prueba calcula el IMC, llama al método que usa HTTP, y verifica la respuesta mockeada.

Con esto hemos usado Wiremock en nuestro proyecto Java.

Conclusiones:

  • Wiremock es muy útil para simular nuestras peticiones HTTP sin que haya la necesidad de que nuestros servicio esten creados.
  • Se puede usar en conjunto con JUnit y/o Mockito.
  • Nos ayuda a realizar pruebas que pueden hallar errores en un futuro y corregirlos antes de que se implemente el código a producción.

Más ejemplos en próximas entregas.

Enlaces:

https://wiremock.org/

Comentarios

Entradas populares de este blog

Programación Windows Batch (CMD) parte 3

Crear ciclos para efectuar operaciones tediosas nos ahorrará tiempo para realizar otras tareas. En está ocasión veremos ciclos con FOR . ¿Cuál es la síntaxis de bucle FOR en Windows Batch? Si está dentro de un archivo *.bat : FOR %%variable IN (seq) DO operaciones Si lo ejecutamos en una terminal: FOR %variable IN (seq) DO operaciones Ejemplo 1 . Recorrer una secuencia de números del 0 al 5: recorrer.bat @ echo off FOR %%i in ( 0 1 2 3 4 5 ) DO echo Hola no. %%i pause Nos imprimirá en pantalla: Hola no. 0 Hola no. 1 Hola no. 2 Hola no. 3 Hola no. 4 Hola no. 5 ¿Puedo usar contadores? Si, se pueden usar. Ejemplo 2 . Uso de contadores: contador.bat @ echo off set numeros = 1 2 3 4 5 6 7 8 9 10 set cont = 0 for %%a in ( %numeros% ) do ( echo Hola no. %%a :: Contador set /a cont+ = 1 ) echo Total: %cont% Este código nos imprimirá, además de los mensajes Hola no. 0 ..., el total de valores conta...

TIOBE index 2024

El índice TIOBE (o índice de la comunidad de programación TIOBE) mide la popularidad de los lenguajes de programación. Su índice no se basa en qué lenguaje de programación es mejor, si tiene mejor perfomance, si posee escalabilidad, si es más sencillo de aprender, de usar, de implementar, etc. Sólo se basa en la popularidad. En el número de referencias ya sea en blogs, foros de consulta, etc. No necesariamente si las empresas lo están usando en alguno de sus desarrollos. Este índice es útil para darse una idea qué lenguaje está cobrando más popularidad y prestigio. Enseguida una tabla con los primeros 5 lenguajes más populares. Índice de Noviembre 2024   Nov 2024  Nov 2023  Change  Programming Language  Ratings  Change  1  1    Python  22.85%  +8.69%  2  3  +  C++  10.64%  +0.29%  3  4  +  Java  9.60%  +1.26%  4 ...

Programación Windows Batch (CMD) parte 4

Siguiendo con la serie de post sobre programación ( 1 , 2 , y 3 ) batch ahora veremos algunas cosas como operaciones aritméticas, operadores lógicos  y uso de ficheros. Cuando somos administradores de servidores o desarrolladores muchas veces tenemos que realizar tareas que nos quitan, relativamente, tiempo valioso que podríamos ocupar para otras cosas (como ver nuestro Facebook, jeje, broma).  Aprender a escribir scripts que nos faciliten algunas tareas siempre es útil. Por ejemplo, conocer todas las características técnicas de nuestro equipo de cómputo nos servirá cuando se realiza peritajes informáticos y soporte al equipo. Realizar respaldos automáticos a nuestras carpetas , archivos y directorios será más sencillo gracias a un script. Pero antes debemos aprender lo básico de la programación en batch. Ejemplo 1. Operaciones aritméticas básicas. aritmetica.bat @ echo off ::Nombre del archivo, imprimirá: aritmetica.bat echo %0 :: Set nos servirá para a...