Skip to content

Commit 01bcd26

Browse files
committed
SWS-651 - Fishined client-side docs
1 parent a066e9a commit 01bcd26

File tree

4 files changed

+208
-12
lines changed

4 files changed

+208
-12
lines changed

src/docbkx/client.xml

Lines changed: 166 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,15 @@ public void marshalWithSoapActionHeader(final Source s) {
510510
to guide you through the process of setting up the mock server.
511511
</para>
512512
</note>
513+
<note>
514+
<para>
515+
Also note that you rely on the standard logging features available in Spring Web Services in your
516+
unit tests.
517+
Sometimes it might be useful to inspect the request or response message to find out why a
518+
particular tests failed.
519+
See <xref linkend="logging"/> for more information.
520+
</para>
521+
</note>
513522
<para>
514523
Consider, for example, this Web service client class:
515524
</para>
@@ -664,10 +673,14 @@ public class CustomerClientIntegrationTest {
664673
<para>
665674
We define expectations by calling <methodname>expect()</methodname> with a
666675
<methodname>payload()</methodname> <interfacename>RequestMatcher</interfacename> provided
667-
by the statically imported <classname>RequestMatchers</classname>.
676+
by the statically imported <classname>RequestMatchers</classname> (see <xref
677+
linkend="client-test-request-matcher"/>).
678+
</para>
679+
<para>
668680
We also set up a response by calling <methodname>andRespond()</methodname> with a
669681
<methodname>withPayload()</methodname> <interfacename>ResponseCreator</interfacename>
670-
provided by the statically imported <classname>ResponseCreators</classname>.
682+
provided by the statically imported <classname>ResponseCreators</classname> (see
683+
<xref linkend="client-test-response-creator"/>).
671684
</para>
672685
<para>
673686
This part of the test might look a bit confusing, but the Code Completion features of your
@@ -698,7 +711,158 @@ public class CustomerClientIntegrationTest {
698711
</callout>
699712
</calloutlist>
700713
</programlistingco>
714+
</section>
715+
<section id="client-test-request-matcher">
716+
<title><interfacename>RequestMatcher</interfacename> and <classname>RequestMatchers</classname></title>
717+
<para>
718+
To verify whether the request message meets certain expectations, the
719+
<classname>MockWebServiceServer</classname> uses the <interfacename>RequestMatcher</interfacename>
720+
strategy interface.
721+
The contract defined by this interface is quite simple:
722+
</para>
723+
<programlisting><![CDATA[public interface RequestMatcher {
724+
725+
void match(URI uri,
726+
WebServiceMessage request)
727+
throws IOException,
728+
AssertionError;
701729
730+
}]]></programlisting>
731+
<para>
732+
You can write your own implementations of this interface, throwing
733+
<classname>AssertionError</classname>s when the message does not meet your expectations, but you
734+
certainly do not have to.
735+
The <classname>RequestMatchers</classname> class provides standard
736+
<interfacename>RequestMatcher</interfacename> implementations for you to use in your tests.
737+
You will typically statically import this class.
738+
</para>
739+
<para>
740+
The <classname>RequestMatchers</classname> class provides the following request matchers:
741+
<informaltable>
742+
<tgroup cols="2">
743+
<thead>
744+
<row>
745+
<entry><classname>RequestMatchers</classname> method</entry>
746+
<entry>Description</entry>
747+
</row>
748+
</thead>
749+
<tbody>
750+
<row>
751+
<entry><methodname>anything()</methodname></entry>
752+
<entry>Expects any sort of request.</entry>
753+
</row>
754+
<row>
755+
<entry><methodname>payload()</methodname></entry>
756+
<entry>Expects a given request payload.</entry>
757+
</row>
758+
<row>
759+
<entry><methodname>validPayload()</methodname></entry>
760+
<entry>Expects the request payload to validate against given XSD schema(s).</entry>
761+
</row>
762+
<row>
763+
<entry><methodname>xpath()</methodname></entry>
764+
<entry>
765+
Expects a given XPath expression to exist, not exist, or evaluate to a given
766+
value.
767+
</entry>
768+
</row>
769+
<row>
770+
<entry><methodname>soapHeader()</methodname></entry>
771+
<entry>Expects a given SOAP header to exist in the request message.</entry>
772+
</row>
773+
<row>
774+
<entry><methodname>connectionTo()</methodname></entry>
775+
<entry>Expects a connection to the given URL.</entry>
776+
</row>
777+
</tbody>
778+
</tgroup>
779+
</informaltable>
780+
You can set up multiple request expectations by chaining <methodname>andExpect()</methodname> calls,
781+
like so:
782+
<programlisting>mockServer.expect(connectionTo("http://example.com")).
783+
andExpect(payload(expectedRequestPayload)).
784+
andExpect(validPayload(schemaResource)).
785+
andRespond(...);
786+
</programlisting>
787+
</para>
788+
<para>
789+
For more information on the request matchers provided by <classname>RequestMatchers</classname>,
790+
refer to the class level Javadoc.
791+
</para>
792+
</section>
793+
<section id="client-test-response-creator">
794+
<title><interfacename>ResponseCreator</interfacename> and <classname>ResponseCreators</classname></title>
795+
<para>
796+
When the request message has been verified and meets the defined expectations, the
797+
<classname>MockWebServiceServer</classname> will create a response message for the
798+
<classname>WebServiceTemplate</classname> to consume.
799+
The server uses the <interfacename>ResponseCreator</interfacename>
800+
strategy interface for this purpose:
801+
</para>
802+
<programlisting><![CDATA[public interface ResponseCreator {
803+
804+
WebServiceMessage createResponse(URI uri,
805+
WebServiceMessage request,
806+
WebServiceMessageFactory messageFactory)
807+
throws IOException;
808+
809+
}]]></programlisting>
810+
<para>
811+
Once again you can write your own implementations of this interface, creating a response message
812+
by using the message factory, but you certainly do not have to, as the
813+
<classname>ResponseCreators</classname> class provides standard
814+
<interfacename>ResponseCreator</interfacename> implementations for you to use in your tests.
815+
You will typically statically import this class.
816+
</para>
817+
<para>
818+
The <classname>ResponseCreators</classname> class provides the following responses:
819+
<informaltable>
820+
<tgroup cols="2">
821+
<thead>
822+
<row>
823+
<entry><classname>ResponseCreators</classname> method</entry>
824+
<entry>Description</entry>
825+
</row>
826+
</thead>
827+
<tbody>
828+
<row>
829+
<entry><methodname>withPayload()</methodname></entry>
830+
<entry>Creates a response message with a given payload.</entry>
831+
</row>
832+
<row>
833+
<entry><methodname>withError()</methodname></entry>
834+
<entry>
835+
Creates an error in the response connection.
836+
This method gives you the opportunity to test your error handling.
837+
</entry>
838+
</row>
839+
<row>
840+
<entry><methodname>withException()</methodname></entry>
841+
<entry>
842+
Throws an exception when reading from the response connection.
843+
This method gives you the opportunity to test your exception handling.
844+
</entry>
845+
</row>
846+
<row>
847+
<entry>
848+
<methodname>withMustUnderstandFault()</methodname>,
849+
<methodname>withClientOrSenderFault()</methodname>,
850+
<methodname>withServerOrReceiverFault()</methodname>, and
851+
<methodname>withVersionMismatchFault()</methodname>
852+
</entry>
853+
<entry>
854+
Creates a response message with a given SOAP fault.
855+
This method gives you the opportunity to test your Fault handling.
856+
</entry>
857+
</row>
858+
</tbody>
859+
</tgroup>
860+
</informaltable>
861+
</para>
862+
<para>
863+
For more information on the request matchers provided by <classname>RequestMatchers</classname>,
864+
refer to the class level Javadoc.
865+
</para>
702866
</section>
703867
</section>
704868
</chapter>

test/src/test/java/org/springframework/ws/test/client/integration/ClientIntegrationTest.java

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,7 @@
2121
import org.springframework.beans.factory.annotation.Autowired;
2222
import org.springframework.test.context.ContextConfiguration;
2323
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
24-
import org.springframework.ws.client.core.WebServiceTemplate;
2524
import org.springframework.ws.test.client.MockWebServiceServer;
26-
import org.springframework.ws.test.integration.CustomerCountRequest;
27-
import org.springframework.ws.test.integration.CustomerCountResponse;
2825
import org.springframework.xml.transform.StringSource;
2926

3027
import org.junit.Before;
@@ -46,13 +43,13 @@
4643
public class ClientIntegrationTest {
4744

4845
@Autowired
49-
private WebServiceTemplate webServiceTemplate;
46+
private CustomerClient client;
5047

5148
private MockWebServiceServer mockServer;
5249

5350
@Before
5451
public void createServer() throws Exception {
55-
mockServer = MockWebServiceServer.createServer(webServiceTemplate);
52+
mockServer = MockWebServiceServer.createServer(client);
5653
}
5754

5855
@Test
@@ -66,11 +63,8 @@ public void basic() throws Exception {
6663

6764
mockServer.expect(payload(expectedRequestPayload)).andRespond(withPayload(responsePayload));
6865

69-
CustomerCountRequest request = new CustomerCountRequest();
70-
request.setCustomerName("John Doe");
71-
72-
CustomerCountResponse response = (CustomerCountResponse) webServiceTemplate.marshalSendAndReceive(request);
73-
assertEquals(10, response.getCustomerCount());
66+
int result = client.getCustomerCount();
67+
assertEquals(10, result);
7468

7569
mockServer.verify();
7670
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright 2005-2010 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.ws.test.client.integration;
18+
19+
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;
20+
import org.springframework.ws.test.integration.CustomerCountRequest;
21+
import org.springframework.ws.test.integration.CustomerCountResponse;
22+
23+
24+
public class CustomerClient extends WebServiceGatewaySupport {
25+
26+
public int getCustomerCount() {
27+
CustomerCountRequest request = new CustomerCountRequest();
28+
request.setCustomerName("John Doe");
29+
30+
CustomerCountResponse response = (CustomerCountResponse) getWebServiceTemplate().marshalSendAndReceive(request);
31+
return response.getCustomerCount();
32+
}
33+
34+
}

test/src/test/resources/org/springframework/ws/test/client/integration/integration-test.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
44
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
55

6+
<bean id="client" class="org.springframework.ws.test.client.integration.CustomerClient">
7+
<property name="webServiceTemplate" ref="webServiceTemplate"/>
8+
</bean>
9+
610
<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
711
<property name="marshaller" ref="marshaller"/>
812
<property name="unmarshaller" ref="marshaller"/>

0 commit comments

Comments
 (0)