diff --git a/src/docbkx/client.xml b/src/docbkx/client.xml index d793549e..745c2201 100644 --- a/src/docbkx/client.xml +++ b/src/docbkx/client.xml @@ -447,9 +447,9 @@ public void marshalWithSoapActionHeader(final Source s) { Web Services 2.0.
- Writing integration tests + Writing client-side integration tests - Spring Web Services 2.0 introduced support for creating Web service client tests. + Spring Web Services 2.0 introduced support for creating Web service client integration tests. In this context, a client is a class that uses the WebServiceTemplate to access a Web service. @@ -463,7 +463,7 @@ public void marshalWithSoapActionHeader(final Source s) { The typical usage of the MockWebServiceServer is: - + Create a MockWebServiceServer instance by calling @@ -501,7 +501,7 @@ public void marshalWithSoapActionHeader(final Source s) { expectations have been met. - + @@ -554,7 +554,7 @@ public class CustomerClient extends WebServiceGatewaySupport { CustomerCountRequest is an object supported by a marshaller. - For instance, it could have a @XmlRootElement annotation + For instance, it can have a @XmlRootElement annotation to be supported by JAXB2. @@ -575,8 +575,8 @@ public class CustomerClient extends WebServiceGatewaySupport { - - + + @@ -604,8 +604,8 @@ import org.junit.runner.RunWith; import static org.junit.Assert.assertEquals; import org.springframework.ws.test.client.MockWebServiceServer; -import static org.springframework.ws.test.client.RequestMatchers.payload; -import static org.springframework.ws.test.client.ResponseCreators.withPayload; +import static org.springframework.ws.test.client.RequestMatchers.*; +import static org.springframework.ws.test.client.ResponseCreators.*; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("integration-test.xml") @@ -622,7 +622,7 @@ public class CustomerClientIntegrationTest { } @Test - public void basic() throws Exception { + public void customerClient() throws Exception { Source requestPayload = new StringSource( "" + "John Doe" + @@ -651,7 +651,7 @@ public class CustomerClientIntegrationTest { - This tests uses the standard testing facilities provided in the Spring Framework. + This test uses the standard testing facilities provided in the Spring Framework. This is not required, but is generally the easiest way to set up the test. diff --git a/src/docbkx/server.xml b/src/docbkx/server.xml index 42b5ce8f..daa03262 100644 --- a/src/docbkx/server.xml +++ b/src/docbkx/server.xml @@ -149,7 +149,7 @@ [servlet-name]-servlet.xml in the WEB-INF directory of your web application and create the beans defined there in a Spring container. In the example above, that means that it looks for '/WEB-INF/spring-ws-servlet.xml'. This file will - contain all of the SWS-specific beans such as endpoints, marshallers and suchlike. + contain all of the Spring Web Services beans such as endpoints, marshallers and suchlike.
Automatic WSDL exposure @@ -583,7 +583,7 @@
-
+
Endpoints Endpoints are the central concept in Spring-WS's server-side support. Endpoints provide access to the @@ -1566,4 +1566,365 @@ public class MyBusinessException extends Exception { ]]>
+
+ Server-side testing + + When it comes to testing your Web service endpoints, there are two possible approaches: + + + + + Write Unit Tests, where you provide (mock) arguments for your endpoint to + consume. + + + The advantage of this approach is that it's quite easy to accomplish (especially for classes + annotated with @Endpoint); the disadvantage is that + you are not really testing the exact content of the XML messages that are sent over the wire. + + + + + Write Integrations Tests, which do test the contents of the message. + + + + + The first approach can easily be accomplished with mocking frameworks such as EasyMock, JMock, etc. + The next section will focus on writing integration tests, using the test features introduced in Spring + Web Services 2.0. + +
+ Writing server-side integration tests + + Spring Web Services 2.0 introduced support for creating endpoint integration tests. + In this context, an endpoint is class handles (SOAP) messages (see ). + + + The integration test support lives in the org.springframework.ws.test.server package. + The core class in that package is the MockWebServiceClient. + The underlying idea is that this client creates a request message, and then sends it over to the + endpoint(s) that are configured in a standard MessageDispatcherServlet + application context (see ). + These endpoints will handle the message, and create a response. + The client then receives this response, and verifies it against registered expectations. + + + The typical usage of the MockWebServiceClient is: + + + + Create a MockWebServiceClient instance by calling + MockWebServiceClient.createClient(ApplicationContext) or + MockWebServiceClient.createClient(WebServiceMessageReceiver, WebServiceMessageFactory). + + + + + Send request messages by calling sendRequest(RequestCreator), + possibly by using the default RequestCreator implementations + provided in RequestCreators (which can be statically imported). + + + + + Set up response expectations by calling andExpect(ResponseMatcher), + possibly by using the default ResponseMatcher implementations + provided in ResponseMatchers (which can be statically imported). + Multiple expectations can be set up by chaining + andExpect(ResponseMatcher) calls. + + + + + + + Note that the MockWebServiceClient (and related classes) offers a + 'fluent' API, so you can typically use the Code Completion features (i.e. ctrl-space) in your IDE + to guide you through the process of setting up the mock server. + + + + + Also note that you rely on the standard logging features available in Spring Web Services in your + unit tests. + Sometimes it might be useful to inspect the request or response message to find out why a + particular tests failed. + See for more information. + + + + Consider, for example, this simple Web service endpoint class: + + + + + + + + + + + + + + + The CustomerEndpoint in annotated with + @Endpoint. + See . + + + + + The getCustomerCount() method takes a + CustomerCountRequest as argument, and returns a + CustomerCountResponse. + Both of these classes are objects supported by a marshaller. + For instance, they can have a @XmlRootElement annotation + to be supported by JAXB2. + + + + + + A typical test for CustomerEndpoint would look like this: + + + + + + + + + + + + + + + + + + + + " + + "John Doe" + + ""); + Source responsePayload = new StringSource( + "" + + "10" + + ""); + + mockClient.sendRequest(withPayload(requestPayload)). + andExpect(payload(responsePayload)); + } +}]]> + + + + The CustomerEndpointIntegrationTest imports the + MockWebServiceClient, and statically imports + RequestCreators and ResponseMatchers. + + + + + This test uses the standard testing facilities provided in the Spring Framework. + This is not required, but is generally the easiest way to set up the test. + + + + + The application context is a standard Spring-WS application context (see + ), read from + spring-ws-servlet.xml. + In this case, the application context will contain a bean definition for + CustomerEndpoint (or a perhaps a + <context:component-scan /> is used). + + + + + In a @Before method, we create a + MockWebServiceClient by using the + createClient factory method. + + + + + We send a request by calling sendRequest() with a + withPayload() RequestCreator + provided by the statically imported RequestCreators (see ). + + + We also set up response expectations by calling andExpect() with a + payload() ResponseMatcher provided + by the statically imported ResponseMatchers (see ). + + + This part of the test might look a bit confusing, but the Code Completion features of your + IDE are of great help. + After typing sendRequest(, simply type ctrl-space, and your IDE + will provide you with a list of possible request creating strategies, provided you + statically imported RequestCreators. + The same applies to andExpect(, provided you statically imported + ResponseMatchers. + + + + +
+
+ <interfacename>RequestCreator</interfacename> and <classname>RequestCreators</classname> + + Initially, the MockWebServiceClient will need to create a request message for the + endpoint to consume. + The client uses the RequestCreator + strategy interface for this purpose: + + + + You can write your own implementations of this interface, creating a request message + by using the message factory, but you certainly do not have to. + The RequestCreators class provides a way to create a + RequestCreator based on a given payload in the + withPayload() method. + You will typically statically import RequestCreators. + +
+
+ <interfacename>ResponseMatcher</interfacename> and <classname>ResponseMatchers</classname> + + When the request message has been processed by the endpoint, and a response has been received, + the MockWebServiceClient can verify whether this response message meets certain + expectations. + The client uses the ResponseMatcher strategy interface for this purpose: + + + + Once again you can write your own implementations of this interface, throwing + AssertionErrors when the message does not meet your expectations, but you + certainly do not have to, as the ResponseMatchers class provides standard + ResponseMatcher implementations for you to use in your tests. + You will typically statically import this class. + + + The ResponseMatchers class provides the following request matchers: + + + + + ResponseMatchers method + Description + + + + + payload() + Expects a given response payload. + + + validPayload() + Expects the response payload to validate against given XSD schema(s). + + + xpath() + + Expects a given XPath expression to exist, not exist, or evaluate to a given + value. + + + + soapHeader() + Expects a given SOAP header to exist in the response message. + + + noFault() + Expects that the response message does not contain a SOAP Fault. + + + + mustUnderstandFault(), + clientOrSenderFault(), + serverOrReceiverFault(), and + versionMismatchFault() + + Expects the response message to contain a specific SOAP Fault. + + + + + You can set up multiple response expectations by chaining andExpect() calls, + like so: + mockClient.sendRequest(...). + andExpect(payload(expectedResponsePayload)). + andExpect(validPayload(schemaResource)); + + + + For more information on the request matchers provided by ResponseMatchers, + refer to the class level Javadoc. + +
+