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 * @RunWith(SpringJUnit4ClassRunner.class)
56 * @ContextConfiguration("applicationContext.xml")
57 * public class MyWebServiceClientIntegrationTest {
58 *
59 * // MyWebServiceClient extends WebServiceGatewaySupport, and is configured in applicationContext.xml
60 * @Autowired
61 * private MyWebServiceClient client;
62 *
63 * private MockWebServiceServer mockServer;
64 *
65 * @Before
66 * public void createServer() throws Exception {
67 * <strong>mockServer = MockWebServiceServer.createServer(client)</strong>;
68 * }
69 *
70 * @Test
71 * public void getCustomerCount() throws Exception {
72 * Source expectedRequestPayload =
73 * new StringSource("<customerCountRequest xmlns=\"http://springframework.org/spring-ws/test\" />");
74 * Source responsePayload = new StringSource("<customerCountResponse xmlns='http://springframework.org/spring-ws/test'>" +
75 * "<customerCount>10</customerCount>" +
76 * "</customerCountResponse>");
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 }