View Javadoc

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;
18  
19  import org.springframework.context.ApplicationContext;
20  import org.springframework.util.Assert;
21  import org.springframework.ws.client.core.WebServiceTemplate;
22  import org.springframework.ws.client.core.support.WebServiceGatewaySupport;
23  import org.springframework.ws.test.support.MockStrategiesHelper;
24  
25  /**
26   * <strong>Main entry point for client-side Web service testing</strong>. Typically used to test a {@link
27   * WebServiceTemplate}, set up expectations on request messages, and create response messages.
28   * <p/>
29   * The typical usage of this class is:
30   * <ol>
31   * <li>Create a {@code MockWebServiceServer} instance by calling {@link #createServer(WebServiceTemplate)},
32   * {@link #createServer(WebServiceGatewaySupport)}, or {@link #createServer(ApplicationContext)}.
33   * <li>Set up request expectations by calling {@link #expect(RequestMatcher)}, possibly by using the default 
34   * {@link RequestMatcher} implementations provided in {@link RequestMatchers} (which can be statically imported).
35   * Multiple expectations can be set up by chaining {@link ResponseActions#andExpect(RequestMatcher)} calls.</li>
36   * <li>Create an appropriate response message by calling
37   * {@link ResponseActions#andRespond(ResponseCreator) andRespond(ResponseCreator)}, possibly by using the default
38   * {@link ResponseCreator} implementations provided in {@link ResponseCreators} (which can be statically imported).</li>
39   * <li>Use the {@code WebServiceTemplate} as normal, either directly of through client code.</li>
40   * <li>Call {@link #verify()}.</ol>
41   * Note that because of the 'fluent' API offered by this class (and related classes), you can typically use the Code
42   * Completion features (i.e. ctrl-space) in your IDE to set up the mocks.
43   * <p/>
44   * For example:
45   * <blockquote><pre>
46   * import org.junit.*;
47   * import org.springframework.beans.factory.annotation.Autowired;
48   * import org.springframework.test.context.ContextConfiguration;
49   * import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
50   * import org.springframework.xml.transform.StringSource;
51   * <strong>import org.springframework.ws.test.client.MockWebServiceServer</strong>;
52   * <strong>import static org.springframework.ws.test.client.RequestMatchers.*</strong>;
53   * <strong>import static org.springframework.ws.test.client.ResponseCreators.*</strong>;
54   *
55   * &#064;RunWith(SpringJUnit4ClassRunner.class)
56   * &#064;ContextConfiguration("applicationContext.xml")
57   * public class MyWebServiceClientIntegrationTest {
58   *
59   *   // MyWebServiceClient extends WebServiceGatewaySupport, and is configured in applicationContext.xml
60   *   &#064;Autowired
61   *   private MyWebServiceClient client;
62   *
63   *   private MockWebServiceServer mockServer;
64   *
65   *   &#064;Before
66   *   public void createServer() throws Exception {
67   *     <strong>mockServer = MockWebServiceServer.createServer(client)</strong>;
68   *   }
69   * 
70   *   &#064;Test
71   *   public void getCustomerCount() throws Exception {
72   *     Source expectedRequestPayload =
73   *       new StringSource("&lt;customerCountRequest xmlns=\"http://springframework.org/spring-ws/test\" /&gt;");
74   *     Source responsePayload = new StringSource("&lt;customerCountResponse xmlns='http://springframework.org/spring-ws/test'&gt;" +
75   *       "&lt;customerCount&gt;10&lt;/customerCount&gt;" +
76   *       "&lt;/customerCountResponse&gt;");
77   *
78   *     <strong>mockServer.expect(payload(expectedRequestPayload)).andRespond(withPayload(responsePayload));</strong>
79   *
80   *     // client.getCustomerCount() uses the WebServiceTemplate
81   *     int customerCount = client.getCustomerCount();
82   *     assertEquals(10, response.getCustomerCount());
83   *
84   *     <strong>mockServer.verify();</strong>
85   *   }
86   * }
87   * </pre></blockquote>
88   *
89   * @author Arjen Poutsma
90   * @author Lukas Krecan
91   * @since 2.0
92   */
93  public class MockWebServiceServer {
94  
95      private final MockWebServiceMessageSender mockMessageSender;
96  
97      private MockWebServiceServer(MockWebServiceMessageSender mockMessageSender) {
98          Assert.notNull(mockMessageSender, "'mockMessageSender' must not be null");
99          this.mockMessageSender = mockMessageSender;
100     }
101 
102     /**
103      * Creates a {@code MockWebServiceServer} instance based on the given {@link WebServiceTemplate}.
104      *
105      * @param webServiceTemplate the web service template
106      * @return the created server
107      */
108     public static MockWebServiceServer createServer(WebServiceTemplate webServiceTemplate) {
109         Assert.notNull(webServiceTemplate, "'webServiceTemplate' must not be null");
110 
111         MockWebServiceMessageSender mockMessageSender = new MockWebServiceMessageSender();
112         webServiceTemplate.setMessageSender(mockMessageSender);
113 
114         return new MockWebServiceServer(mockMessageSender);
115     }
116 
117     /**
118      * Creates a {@code MockWebServiceServer} instance based on the given {@link WebServiceGatewaySupport}.
119      *
120      * @param gatewaySupport the client class
121      * @return the created server
122      */
123     public static MockWebServiceServer createServer(WebServiceGatewaySupport gatewaySupport) {
124         Assert.notNull(gatewaySupport, "'gatewaySupport' must not be null");
125         return createServer(gatewaySupport.getWebServiceTemplate());
126     }
127 
128     /**
129      * Creates a {@code MockWebServiceServer} instance based on the given {@link ApplicationContext}.
130      * <p/>
131      * This factory method will try and find a configured {@link WebServiceTemplate} in the given application context.
132      * If no template can be found, it will try and find a {@link WebServiceGatewaySupport}, and use its configured
133      * template. If neither can be found, an exception is thrown.
134      *
135      * @param applicationContext the application context to base the client on
136      * @return the created server
137      * @throws IllegalArgumentException if the given application context contains neither a {@link WebServiceTemplate}
138      *                                  nor a {@link WebServiceGatewaySupport}.
139      */
140     public static MockWebServiceServer createServer(ApplicationContext applicationContext) {
141         MockStrategiesHelper strategiesHelper = new MockStrategiesHelper(applicationContext);
142         WebServiceTemplate webServiceTemplate = strategiesHelper.getStrategy(WebServiceTemplate.class);
143         if (webServiceTemplate != null) {
144             return createServer(webServiceTemplate);
145         }
146         WebServiceGatewaySupport gatewaySupport = strategiesHelper.getStrategy(WebServiceGatewaySupport.class);
147         if (gatewaySupport != null) {
148             return createServer(gatewaySupport);
149         }
150         throw new IllegalArgumentException(
151                 "Could not find either WebServiceTemplate or WebServiceGatewaySupport in application context");
152     }
153 
154     /**
155      * Records an expectation specified by the given {@link RequestMatcher}. Returns a {@link ResponseActions} object
156      * that allows for creating the response, or to set up more expectations.
157      *
158      * @param requestMatcher the request matcher expected
159      * @return the response actions
160      */
161     public ResponseActions expect(RequestMatcher requestMatcher) {
162         MockSenderConnection connection = mockMessageSender.expectNewConnection();
163         connection.addRequestMatcher(requestMatcher);
164         return connection;
165     }
166 
167     /**
168      * Verifies that all expectations were met.
169      *
170      * @throws AssertionError in case of unmet expectations
171      */
172     public void verify() {
173         mockMessageSender.verifyConnections();
174     }
175     
176 
177 
178 
179 }