Spring WS Server Side Integration Testing

This tutorial shows how to create integration tests for your spring ws soap endpoints using JUnit. Spring WS has a great framework for writing clean and powerful integration tests. By using the MockWebServiceClient we can make requests to our soap services. We can create requests using RequestCreators and verify the responses using ResponseMatchers. This also allows us to validate the request/response with an XSD Schema and to validate the response for known exceptional cases.

<dependency>
    <groupId>org.springframework.ws</groupId>
    <artifactId>spring-ws-test</artifactId>
    <version>2.2.4.RELEASE</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>4.2.5.RELEASE</version>
    <scope>test</scope>
</dependency>

We are going to test the following service. We made a very basic service that accepts a GetBeerRequest and evaluates the id. If the id == 0 then an exception will be thrown. Finally we return a GetBeerResponse.

package com.memorynotfound.server;

import com.memorynotfound.beer.*;
import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
import org.springframework.ws.server.endpoint.annotation.RequestPayload;
import org.springframework.ws.server.endpoint.annotation.ResponsePayload;

@Endpoint
public class BeerEndpoint {

    public static final String NAMESPACE_URI = "http://memorynotfound.com/beer";

    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "getBeerRequest")
    @ResponsePayload
    public GetBeerResponse getBeer(@RequestPayload GetBeerRequest request) {

        if (request.getId() == 0){
            throw new RuntimeException("id cannot be 0");
        }

        // empty response
        return new GetBeerResponse();
    }

}

We configure our endpoint using the following spring java configuration.

package com.memorynotfound.server;

import com.memorynotfound.server.BeerEndpoint;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.ws.config.annotation.EnableWs;
import org.springframework.ws.config.annotation.WsConfigurerAdapter;
import org.springframework.ws.server.EndpointInterceptor;
import org.springframework.ws.soap.server.endpoint.SoapFaultAnnotationExceptionResolver;
import org.springframework.ws.soap.server.endpoint.SoapFaultMappingExceptionResolver;
import org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor;
import org.springframework.ws.transport.http.MessageDispatcherServlet;
import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition;
import org.springframework.xml.xsd.SimpleXsdSchema;
import org.springframework.xml.xsd.XsdSchema;

@EnableWs
@Configuration
@ComponentScan
public class SoapServerConfig extends WsConfigurerAdapter {

    @Bean
    public ServletRegistrationBean messageDispatcherServlet(ApplicationContext appContext){
        MessageDispatcherServlet servlet = new MessageDispatcherServlet();
        servlet.setApplicationContext(appContext);
        servlet.setTransformWsdlLocations(true);
        return new ServletRegistrationBean(servlet, "/ws/*");
    }

    @Bean(name = "beers")
    public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema schema){
        DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
        wsdl11Definition.setPortTypeName("BeersPort");
        wsdl11Definition.setLocationUri("/ws");
        wsdl11Definition.setTargetNamespace(BeerEndpoint.NAMESPACE_URI);
        wsdl11Definition.setSchema(schema);
        return wsdl11Definition;
    }

    @Bean
    public XsdSchema beersSchema(){
        return new SimpleXsdSchema(new ClassPathResource("xsd/beers.xsd"));
    }

}

Spring WS provides an easy framework for writing clean integration tests for your soap endpoints. We start by adding the SpringJUnit4ClassRunner with the @RunWith annotation. Then we annotate the class using the @ContextConfiguration annotation and add our configuration file we created earlier. Now the class is able to inject spring dependencies, we can create a MockWebServiceClient. This client lets us make requests to our created soap endpoints. We can create requests using RequestCreators and verify the responses using ResponseMatchers. This also allows us to validate the request/response with an XSD Schema and to validate the response for known exceptional cases.

package com.memorynotfound.spring.ws;

import com.memorynotfound.server.SoapServerConfig;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.ws.test.server.MockWebServiceClient;
import org.springframework.xml.transform.StringSource;
import javax.xml.transform.Source;
import java.io.IOException;

import static org.springframework.ws.test.server.RequestCreators.withPayload;
import static org.springframework.ws.test.server.ResponseMatchers.*;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SoapServerConfig.class)
public class BeerEndpointIntegrationTest {

    @Autowired
    private ApplicationContext applicationContext;

    private MockWebServiceClient mockClient;
    private Resource xsdSchema = new ClassPathResource("xsd/beers.xsd");

    @Before
    public void init(){
        mockClient = MockWebServiceClient.createClient(applicationContext);
    }

    @Test
    public void valid_xsd_request_response_test() throws IOException {
        Source requestPayload = new StringSource(
                "<ns2:getBeerRequest xmlns:ns2=\"http://memorynotfound.com/beer\">" +
                        "<ns2:id>1</ns2:id>" +
                "</ns2:getBeerRequest>");

        Source responsePayload = new StringSource(
                "<ns2:getBeerResponse xmlns:ns2=\"http://memorynotfound.com/beer\"></ns2:getBeerResponse>");

        mockClient
                .sendRequest(withPayload(requestPayload))
                .andExpect(noFault())
                .andExpect(payload(responsePayload))
                .andExpect(validPayload(xsdSchema));
    }

    @Test
    public void id_cannot_be_0_test() throws IOException {
        Source requestPayload = new StringSource(
                "<ns2:getBeerRequest xmlns:ns2=\"http://memorynotfound.com/beer\">" +
                        "<ns2:id>0</ns2:id>" +
                        "</ns2:getBeerRequest>");

        mockClient
                .sendRequest(withPayload(requestPayload))
                .andExpect(serverOrReceiverFault());
    }
}

References

Download

You may also like...