-
Notifications
You must be signed in to change notification settings - Fork 3
Unit Testing
Spring WS 2.0 testing framework allows you to write simple integration test. Even though they are executed by JUnit, we can not call them unit tests. More beans are tested together so I call them integration or functional tests. If you want to write real unit tests, Smock is here to help you.
If your WS is simple it's also simple to Unit test it. You just have to create arguments and verify the response. But if the payload is more complicated the test starts getting messy. You have the build the payload in Java and it's usually long and ugly code. If you use Smock, the code can look like this.
import static net.javacrumbs.smock.common.server.ServerTestHelper.*;
import static org.springframework.ws.test.server.ResponseMatchers.*;
...
public class EndpointUnitTest {
private AirlineEndpoint endpoint = new AirlineEndpoint();
@Test
public void testCompare() throws Exception {
GetFlightsRequest request = createRequest("request1.xml", GetFlightsRequest.class);
GetFlightsResponse response = endpoint.getFlights(request);
validate(response).andExpect(message("response1.xml"));
}
@Test
public void testAssertXPath() throws Exception {
GetFlightsRequest request = createRequest("request1.xml", GetFlightsRequest.class);
GetFlightsResponse response = endpoint.getFlights(request);
validate(response).andExpect(xpath("//ns:from/ns:code",NS_MAP).evaluatesTo("PRG"));
}
}
createRequest loads a resource and deserializes it to GetFlightsRequest. You can use all marshalling mechanisms that are supported by Spring WS. Method validate allows you to validate the response using standard ResponseMatchers either from Spring WS 2.0, from Smock or your own.
Client side unit testing is little bit more complicated. You need to use some mock library like EasyMock or Mockito. Let's assume that you are using EasyMock.
First of all, you have to add Smock EasyMock dependency.
<dependency>
<groupId>net.javacrumbs</groupId>
<artifactId>smock-easymock</artifactId>
<version>0.5</version>
<scope>test</scope>
</dependency>
Then you can write the test
import static net.javacrumbs.smock.easymock.client.SmockEasyMockClient.*;
import static org.easymock.EasyMock.*;
...
public class ClientEasyMockTest {
private AirlineClient airlineClient;
private WebServiceOperations webServiceTemplate;
@Before
public void setUpMocks() throws Exception {
airlineClient = new AirlineClient();
webServiceTemplate = createMock(WebServiceOperations.class);
airlineClient.setWsTemplate(webServiceTemplate);
}
@Test
public void testSimple()
{
expect(webServiceTemplate.marshalSendAndReceive(anyObject()))
.andReturn(response("response1.xml", GetFlightsResponse.class));
replay(webServiceTemplate);
List<Flight> flights = airlineClient.getFlights("PRG", "DUB");
assertEquals(1, flights.size());
verify(webServiceTemplate);
}
@Test
public void testVerifyRequest()
{
expect(webServiceTemplate.marshalSendAndReceive(is(message("request1.xml"))))
.andReturn(response("response1.xml", GetFlightsResponse.class));
replay(webServiceTemplate);
List<Flight> flights = airlineClient.getFlights("PRG", "DUB");
assertEquals(1, flights.size());
verify(webServiceTemplate);
}
}
Again, the method is allows you to use standard RequestMatchers with EasyMock and method response deserializes response from a resource.