Spring WS Client Side Integration Testing
This example shows how to write client side integration tests using Spring WS and JUnit. Spring WS is a great framework for writing Soap Services and it allows you to easily create integration tests. When we want to validate the client side code we can create unit tests with JUnit. Simply create a MockWebServiceServer
class, using this class allows us to verify behaviour of our client.
Make sure the following dependencies are registered in your project.
<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 created a simple client by extending form the WebServiceGatewaySupport
class. This allows us to get the WebServiceTemplate
which we use to make a soap request.
package com.memorynotfound.client;
import com.memorynotfound.beer.GetBeerRequest;
import com.memorynotfound.beer.GetBeerResponse;
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;
public class BeerClient extends WebServiceGatewaySupport {
public GetBeerResponse getBeer(int id) {
GetBeerRequest request = new GetBeerRequest();
request.setId(id);
return (GetBeerResponse) getWebServiceTemplate()
.marshalSendAndReceive(request);
}
}
We use the following configuration to initialize our client and register a JAX-B marshaller for converting the requests and responses to and from XML.
package com.memorynotfound.client;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
@Configuration
public class SoapClientConfig {
@Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("com.memorynotfound.beer");
return marshaller;
}
@Bean
public BeerClient weatherClient(Jaxb2Marshaller marshaller) {
BeerClient client = new BeerClient();
client.setDefaultUri("http://localhost:8080/ws/beer");
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
return client;
}
}
Annotate your class with @RunWith
annotation and register the SpringJUnit4ClassRunner
class to make your tests aware that you are using spring. Next add the @ContextConfiguration
annotation to register the soap client configuration file. Now that we are able to use spring dependency injection in our tests we can create a MockWebServiceServer
class and initialize it with our soap client. We use the MockWebServiceServer
to verify the expected behaviour of our soap client.
package com.memorynotfound.spring.ws;
import com.memorynotfound.beer.GetBeerResponse;
import com.memorynotfound.client.BeerClient;
import com.memorynotfound.client.SoapClientConfig;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
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.client.MockWebServiceServer;
import org.springframework.xml.transform.StringSource;
import javax.xml.transform.Source;
import java.io.IOException;
import static org.hibernate.validator.internal.util.Contracts.assertNotNull;
import static org.springframework.ws.test.client.RequestMatchers.payload;
import static org.springframework.ws.test.client.ResponseCreators.withPayload;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SoapClientConfig.class)
public class BeerClientIntegrationTest {
@Autowired
private BeerClient client;
private MockWebServiceServer mockServer;
@Before
public void init(){
mockServer = MockWebServiceServer.createServer(client);
}
@Test
public void valid_xsd_request_response_test() throws IOException {
Source requestPayload = new StringSource(
"<ns2:getBeerRequest xmlns:ns2=\"https://memorynotfound.com/beer\">" +
"<ns2:id>1</ns2:id>" +
"</ns2:getBeerRequest>");
Source responsePayload = new StringSource(
"<ns2:getBeerResponse xmlns:ns2=\"https://memorynotfound.com/beer\"></ns2:getBeerResponse>");
mockServer
.expect(payload(requestPayload))
.andRespond(withPayload(responsePayload));
GetBeerResponse response = client.getBeer(1);
assertNotNull(response);
mockServer.verify();
}
}