domingo, 2 de mayo de 2021

Como emular un servicio SOAP con Wiremock

Ya hemos visto varios ejemplos de como usar wiremock. Y siempre lo hemos usado para simular llamadas REST, hoy veremos como también podemos simular llamadas SOAP. 

Como vamos a ver, si tenemos un poco de conocimiento sobre Wiremock, será una tarea sencilla. Por lo que veremos nos podremos dar más detalles, empezando por la creación del WebService, su cliente y despues el test JUnit en el que usaremos Wiremock.

Para empezar si queremos hacer un Servicio Web podemos utilizar la librería de JAX-WS, en cuatro sencillos pasos:
  • Añadir la anotación @WebService a la clase que contenga la lógica.
  • Añadir la anotación @WebMethod a cada uno de los métodos que queramos exponer. 
  • Crear un fichero sun-jaxws.xml en la carpeta WEB-INF donde se indique la clase a exponer.
  • Modificar el fichero web.xml para añadir el servlet de WSServlet y el listener WSServletContextListener.
Si quieres más información puedes ver un post sobre el tema aquí

El siguiente paso será crear un cliente. Esto lo podemos hacer más facilmente todavia, a través de la herramienta wsimport y teniendo acceso al fichero WSDL que tendremos obtendremos al desplegar el WebService. El código del cliente lo podemos obtener con el siguiente comando:

wsimport -keep .\BookServiceImplService.wsdl

Si quieres más información puedes ver un post sobre el tema aquí

Una vez que tenemos nuestro cliente, es el momento de ponernos manos a la obra y crear nuestro test JUnit con Wiremock. El primer paso incluir la dependencia:

<dependency>
	<groupId>com.github.tomakehurst</groupId>
	<artifactId>wiremock</artifactId>
	<version>2.25.1</version>
	<scope>test</scope>
</dependency>

Luego configuramos el WiremockServer en la clase de pruebas. A través de este WiremockServer, podremos configurar en que puerto estará escuchando el Wiremock, cual será la carpeta base a usar o mostrar información a través de la consola de salida, aparte de muchas más cosas. Ejemplo:

private final static String FOLDER = "src/test/resources/wiremock";
private static WireMockServer wireMockServer;

@BeforeAll
public static void setup() {
	wireMockServer = new WireMockServer(WireMockConfiguration
		.wireMockConfig().withRootDirectory(FOLDER).port(8080)
		.notifier(new ConsoleNotifier(true)));
	wireMockServer.start();
}

A lo mejor la parte más dificil a la hora de crear el test, es identificar cual debe ser la respuesta a obtener por el Wiremock. Para ello igual podemos ayudarnos de la herramienta SOAPUI, la cual en base a un WSDL nos permite obtener request y response de ejemplo. 

Ahora toca hacer el test. Resumiendo mucho, la diferencia principal entre un servicio REST y otro SOAP, es que el primero se envía y recibe JSON y en el segundo XML. Por tanto para nuestras pruebas deberemos indicar la URL como en un servicio REST, pero indicando que va a hacer una petición y recibir XML. Esto lo podemos hacer a través de los siguientes pasos:
  • Recibir una llamada de tipo POST
  • Indicar que en la cabecera Content-Type vamos a recibir 'text/xml'.
  • Indicar que en la cabecera SOAPAction estará incluido el método a llamar. 
  • La respuesta será un fichero XML con el formato correcto. Que hemos podido obtener de SOAPUI. 
@Test
public void getAll() {
    wireMockServer.stubFor(post(urlPathEqualTo("/soapWSExample/bookService"))
	.withHeader("Content-Type", WireMock.containing("text/xml"))
	.withHeader("SoapAction", WireMock.containing("getAllRequest"))
	.willReturn(aResponse().withBodyFile("getAll.xml")));

    BookServiceImplService service = new BookServiceImplService();
    List<Book> list = service.getBookServiceImplPort().getAll();
    assertThat(list.size(), equalTo(3));
}

Como veis, un post corto y sencillo. Sobre todo si tenéis conocimientos previos de Wiremock. 

No hay comentarios:

Publicar un comentario