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 }