Mock de un WS mediante Spring WS

De Dos Ideas.
Revisión del 14:16 9 abr 2012 de MaTT (discusión | contribuciones) (Ejemplo)
Saltar a: navegación, buscar

Introducción

En esta página explicaremos de qué forma podemos simular el entorno de un Web Service en memoria, de modo tal de poder realizar un test de componentes contra dicho entorno.

Requerimientos

Para mockear un Web Service mediante Spring WS, necesitaremos agregar a nuestro proyecto los siguientes jars:

  • jaxb-api-2.0.jar
  • jaxb-impl-2.0.3.jar
  • xalan-2.7.1.jar (importante que sea esta versión o superior)
  • xmlunit-1.1.jar

Ejemplo

Básicamente, el código para crear un test contra dicho entorno será como el siguiente:

@RunWith(SpringJUnit4ClassRunner.class)

// indicamos a Spring que levante los archivos de configuración que veremos más adelante @ContextConfiguration("spring-configuration.xml") public class ClienteIntegracionTest {

// Creamos el request a enviarle al WS private String request = "<ns2:ClienteRequest xmlns:ns2='http://ejemplo.com.ar/'><ns2:APELLIDO_RAZONSOCIAL>Una razon social</ns2:APELLIDO_RAZONSOCIAL></ns2:ClienteRequest>";

// Creamos el response que nos responderá el WS private String response = "<ns2:ClienteResponse xmlns:ns2='http://ejemplo.com.ar/'><ns2:ID_CLIENTE>123</ns2:ID_CLIENTE></ns2:ClienteResponse>";

//Inyectamos el WebServiceTemplate @Autowired private WebServiceTemplate webServiceTemplate;

// Mockeamos el WebServiceServer private MockWebServiceServer server;

// Clase nuestra que lo consumirá @Autowired private Cliente cliente;

// En el Before levantamos el server pasandole como parámetro al constructor // el webServiceTemplate @Before public void setup() { server = MockWebServiceServer.createServer(webServiceTemplate); }

@Test public void testInvocacionWs() {

// Le damos comportamiento a nuestro WS con el request y el response // antes configurado server.expect(RequestMatchers.payload(new StringSource(request))).andRespond(ResponseCreators.withPayload(new StringSource(response)));

cliente.invocarMetodoQueLlamaAlWs();

// Nos aseguramos que el servicio fue invocado server.verify(); }

}

Dentro de los archivos de configuración que levante Spring, tendremos que configurarle los siguientes beans:

<bean id="wsTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
 <property name="defaultUri" value="http://localhost:8080/" />
 <property name="marshaller" ref="marshaller" />
 <property name="unmarshaller" ref="marshaller" />
</bean>
<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
 <property name="classesToBeBound">
  <list>
   <value>com.dosideas.ejemplo.schemas.ClienteRequest</value>
   <value>com.dosideas.ejemplo.schemas.ClienteResponse</value>
  </list>
 </property>
</bean>

Finalmente, el método de nuestra clase cliente, deberá contener

public void invocarMetodoQueLlamaAlWs() { ... ClienteRequest clienteRequest = new ClienteRequest(); ... ClienteResponse clienteResponse = (clienteResponse) webServiceTemplate

       .marshalSendAndReceive(clienteRequest);

... }

Otra forma de generar un mock

Spring WS Test project es una libreria que simplifica los test que realizamos utilizando spring-ws.

Requerimientos

  • spring-ws-test.jar

Ejemplo

Básicamente, el código para crear un test será como el siguiente:

@RunWith(SpringJUnit4ClassRunner.class) // indicamos a Spring que levante los archivos de configuración que veremos más adelante @ContextConfiguration(locations = {"spring-configuration.xml", "spring-ws-responses-mock.xml"})

public class ClienteComponenteTest {

// Clase nuestra que lo consumirá @Autowired private Cliente cliente;

@Test public void testInvocacionWs() {

Collection<Algo> coleccion = cliente.invocarMetodoQueLlamaAlWs(param1);
assertNotNull(coleccion )

}

}

En nuestra clase de test, debemos agregar al contexto de spring un xml (ej: spring-ws-responses-mock.xml) con la siguiente configuracion:

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
   <bean id="messageSender" class="net.javacrumbs.springws.test.MockWebServiceMessageSender"/>
   <bean class="net.javacrumbs.springws.test.util.MockMessageSenderInjector"/>
   <bean class="net.javacrumbs.springws.test.generator.DefaultResponseGeneratorFactoryBean">
       <property name="namespaceMap">
           <map>
               <entry key="soapenv" value="http://schemas.xmlsoap.org/soap/envelope/"/>
           </map>
       </property>
       <property name="XPathExpressions">
           <list>
               <value>concat('/com/tma/dosideas/ws/mock/response/',local-name(//soapenv:Body/*[1]),'-response-', //APELLIDO_RAZONSOCIAL, '.xml')</value>
           </list>
       </property>
   </bean>

</beans>

En la primera parte del xml declaramos un mock message sender que luego inyectamos en nuestro WebServiceTemplate de spring-ws para que las peticiones del template sean atendidas por el mock. La clase DefaultResponseGeneratorFactoryBean se encarga de buscar en los archivos de un directorio, el xml de response para el request que tenga el valor "Una razon social" en el campo APELLIDO_RAZONSOCIAL.

  • REQUEST

<?xml version="1.0" encoding="UTF-8"?> <ns2:ClienteRequest xmlns:ns2='http://ejemplo.com.ar'> <ns2:APELLIDO_RAZONSOCIAL>Una razon social</ns2:APELLIDO_RAZONSOCIAL> </ns2:ClienteRequest>

  • RESPONSE con el siguiente formato: operacion-response-APELLIDO_RAZONSOCIAL.xml

<?xml version="1.0" encoding="UTF-8"?> <ns2:ClienteResponse xmlns:ns2='http://ejemplo.com.ar'> <ns2:ID_CLIENTE>123</ns2:ID_CLIENTE> </ns2:ClienteResponse>

Fuente