diff --git a/test/src/main/java/org/springframework/ws/test/client/MockWebServiceServer.java b/test/src/main/java/org/springframework/ws/test/client/MockWebServiceServer.java index a7eb1ac6..f78016e9 100644 --- a/test/src/main/java/org/springframework/ws/test/client/MockWebServiceServer.java +++ b/test/src/main/java/org/springframework/ws/test/client/MockWebServiceServer.java @@ -16,11 +16,81 @@ package org.springframework.ws.test.client; +import org.springframework.beans.factory.BeanInitializationException; +import org.springframework.context.ApplicationContext; import org.springframework.util.Assert; import org.springframework.ws.client.core.WebServiceTemplate; +import org.springframework.ws.client.core.support.WebServiceGatewaySupport; +import org.springframework.ws.test.support.MockStrategiesHelper; /** + * Main entry point for client-side Web service testing. Typically used to test a {@link + * WebServiceTemplate}, set up expectations on request messages, and create response messages. + *

+ * The typical usage of this class is: + *

    + *
  1. Create a {@code MockWebServiceServer} instance by calling {@link #createServer(WebServiceTemplate)}. + * Typically, the template is configured as a Spring bean, either explicitly or as a property of a class that extends + * {@link WebServiceGatewaySupport WebServiceGatewaySupport}.
  2. + *
  3. Set up request expectations by calling {@link #expect(RequestMatcher)}, possibly by using the default + * {@link RequestMatcher} implementations provided in {@link RequestMatchers} (which can be statically imported). + * Multiple expectations can be set up by chaining {@link ResponseActions#andExpect(RequestMatcher)} calls.
  4. + *
  5. Create an appropriate response message by calling + * {@link ResponseActions#andRespond(ResponseCreator) andRespond(ResponseCreator)}, possibly by using the default + * {@link ResponseCreator} implementations provided in {@link ResponseCreators} (which can be statically imported).
  6. + *
  7. Use the {@code WebServiceTemplate} as normal, either directly of through client code.
  8. + *
  9. Call {@link #verify()}.
+ * Note that because of the 'fluent' API offered by this class (and related classes), you can typically use the Code + * Completion features (i.e. ctrl-space) in your IDE to set up the mocks. + *

+ * For example: + *

+ * import org.junit.*;
+ * import org.springframework.beans.factory.annotation.Autowired;
+ * import org.springframework.test.context.ContextConfiguration;
+ * import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+ * import org.springframework.xml.transform.StringSource;
+ * import org.springframework.ws.test.client.MockWebServiceServer;
+ * import static org.springframework.ws.test.client.RequestMatchers.*;
+ * import static org.springframework.ws.test.client.ResponseCreators.*;
+ *
+ * @RunWith(SpringJUnit4ClassRunner.class)
+ * @ContextConfiguration("applicationContext.xml")
+ * public class MyWebServiceClientIntegrationTest {
+ *
+ *   // MyWebServiceClient extends WebServiceGatewaySupport, and is configured in applicationContext.xml
+ *   @Autowired
+ *   private MyWebServiceClient client;
+ *
+ *   private MockWebServiceServer mockServer;
+ *
+ *   @Before
+ *   public void createServer() throws Exception {
+ *     mockServer = MockWebServiceServer.createServer(client.getWebServiceTemplate());
+ *   }
+ * 
+ *   @Test
+ *   public void getCustomerCount() throws Exception {
+ *     Source expectedRequestPayload =
+ *       new StringSource("<customerCountRequest xmlns=\"http://springframework.org/spring-ws/test\" />");
+ *     Source responsePayload = new StringSource("<customerCountResponse xmlns='http://springframework.org/spring-ws/test'>" +
+ *       "<customerCount>10</customerCount>" +
+ *       "</customerCountResponse>");
+ *
+ *     mockServer.expect(payload(expectedRequestPayload)).andRespond(withPayload(responsePayload));
+ *
+ *     // client.getCustomerCount() uses the WebServiceTemplate
+ *     int customerCount = client.getCustomerCount();
+ *     assertEquals(10, response.getCustomerCount());
+ *
+ *     mockServer.verify();
+ *   }
+ * }
+ * 
+ * * @author Arjen Poutsma + * @author Lukas Krecan + * @since 2.0 */ public class MockWebServiceServer { @@ -31,6 +101,12 @@ public class MockWebServiceServer { this.mockMessageSender = mockMessageSender; } + /** + * Creates a {@code MockWebServiceServer} instance based on the given {@link WebServiceTemplate}. + * + * @param webServiceTemplate the web service template + * @return the created server + */ public static MockWebServiceServer createServer(WebServiceTemplate webServiceTemplate) { Assert.notNull(webServiceTemplate, "'webServiceTemplate' must not be null"); @@ -40,9 +116,46 @@ public class MockWebServiceServer { return new MockWebServiceServer(mockMessageSender); } + /** + * Creates a {@code MockWebServiceServer} instance based on the given {@link WebServiceGatewaySupport}. + * + * @param gatewaySupport the client class + * @return the created server + */ + public static MockWebServiceServer createServer(WebServiceGatewaySupport gatewaySupport) { + Assert.notNull(gatewaySupport, "'gatewaySupport' must not be null"); + return createServer(gatewaySupport.getWebServiceTemplate()); + } + + /** + * Creates a {@code MockWebServiceServer} instance based on the given {@link ApplicationContext}. + *

+ * This factory method will try and find a configured {@link WebServiceTemplate} in the given application context. + * If no template can be found, it will try and find a {@link WebServiceGatewaySupport}, and use its configured + * template. If neither can be found, an exception is thrown. + * + * @param applicationContext the application context to base the client on + * @return the created server + * @throws BeanInitializationException if the given application context contains neither a {@link + * WebServiceTemplate} nor a {@link WebServiceGatewaySupport}. + */ + public static MockWebServiceServer createServer(ApplicationContext applicationContext) { + MockStrategiesHelper strategiesHelper = new MockStrategiesHelper(applicationContext); + WebServiceTemplate webServiceTemplate = strategiesHelper.getStrategy(WebServiceTemplate.class); + if (webServiceTemplate != null) { + return createServer(webServiceTemplate); + } + WebServiceGatewaySupport gatewaySupport = strategiesHelper.getStrategy(WebServiceGatewaySupport.class); + if (gatewaySupport != null) { + return createServer(gatewaySupport); + } + throw new BeanInitializationException( + "Could not find either WebServiceTemplate or WebServiceGatewaySupport in application context"); + } + /** * Records an expectation specified by the given {@link RequestMatcher}. Returns a {@link ResponseActions} object - * that allows for setting up the response, or more expectations. + * that allows for creating the response, or to set up more expectations. * * @param requestMatcher the request matcher expected * @return the response actions diff --git a/test/src/main/java/org/springframework/ws/test/server/MockWebServiceClient.java b/test/src/main/java/org/springframework/ws/test/server/MockWebServiceClient.java index 83c6bf0e..e131a4d3 100644 --- a/test/src/main/java/org/springframework/ws/test/server/MockWebServiceClient.java +++ b/test/src/main/java/org/springframework/ws/test/server/MockWebServiceClient.java @@ -17,18 +17,16 @@ package org.springframework.ws.test.server; import java.io.IOException; -import java.util.Map; -import org.springframework.beans.factory.BeanInitializationException; import org.springframework.context.ApplicationContext; import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; import org.springframework.ws.WebServiceMessage; import org.springframework.ws.WebServiceMessageFactory; import org.springframework.ws.context.DefaultMessageContext; import org.springframework.ws.context.MessageContext; import org.springframework.ws.soap.saaj.SaajSoapMessageFactory; import org.springframework.ws.soap.server.SoapMessageDispatcher; +import org.springframework.ws.test.support.MockStrategiesHelper; import org.springframework.ws.transport.WebServiceMessageReceiver; import org.apache.commons.logging.Log; @@ -110,56 +108,17 @@ public class MockWebServiceClient { * @return the created client */ public static MockWebServiceClient createClient(ApplicationContext applicationContext) { - WebServiceMessageReceiver messageReceiver = getMessageReceiver(applicationContext); - WebServiceMessageFactory messageFactory = getMessageFactory(applicationContext); + Assert.notNull(applicationContext, "'applicationContext' must not be null"); + + MockStrategiesHelper strategiesHelper = new MockStrategiesHelper(applicationContext); + + WebServiceMessageReceiver messageReceiver = + strategiesHelper.getStrategy(WebServiceMessageReceiver.class, SoapMessageDispatcher.class); + WebServiceMessageFactory messageFactory = + strategiesHelper.getStrategy(WebServiceMessageFactory.class, SaajSoapMessageFactory.class); return new MockWebServiceClient(messageReceiver, messageFactory); } - private static WebServiceMessageReceiver getMessageReceiver(ApplicationContext applicationContext) { - WebServiceMessageReceiver messageReceiver = getStrategy(applicationContext, WebServiceMessageReceiver.class); - if (messageReceiver == null) { - if (logger.isDebugEnabled()) { - logger.debug("No WebServiceMessageReceiver found, using default"); - } - SoapMessageDispatcher soapMessageDispatcher = new SoapMessageDispatcher(); - soapMessageDispatcher.setApplicationContext(applicationContext); - messageReceiver = soapMessageDispatcher; - } - return messageReceiver; - } - - private static WebServiceMessageFactory getMessageFactory(ApplicationContext applicationContext) { - WebServiceMessageFactory messageFactory = getStrategy(applicationContext, WebServiceMessageFactory.class); - if (messageFactory == null) { - if (logger.isDebugEnabled()) { - logger.debug("No WebServiceMessageFactory found, using default"); - } - SaajSoapMessageFactory saajSoapMessageFactory = new SaajSoapMessageFactory(); - saajSoapMessageFactory.afterPropertiesSet(); - messageFactory = saajSoapMessageFactory; - } - return messageFactory; - } - - private static T getStrategy(ApplicationContext applicationContext, Class strategyInterface) { - Map map = applicationContext.getBeansOfType(strategyInterface); - if (map.isEmpty()) { - return null; - } - else if (map.size() == 1) { - Map.Entry entry = map.entrySet().iterator().next(); - if (logger.isDebugEnabled()) { - logger.debug("Using " + ClassUtils.getShortName(strategyInterface) + " [" + entry.getKey() + "]"); - } - return entry.getValue(); - } - else { - throw new BeanInitializationException( - "Could not find exactly 1 " + ClassUtils.getShortName(strategyInterface) + - " in application context"); - } - } - // Sending /** diff --git a/test/src/main/java/org/springframework/ws/test/support/MockStrategiesHelper.java b/test/src/main/java/org/springframework/ws/test/support/MockStrategiesHelper.java index 24cac8d3..b49f5e97 100644 --- a/test/src/main/java/org/springframework/ws/test/support/MockStrategiesHelper.java +++ b/test/src/main/java/org/springframework/ws/test/support/MockStrategiesHelper.java @@ -18,8 +18,13 @@ package org.springframework.ws.test.support; import java.util.Map; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanInitializationException; +import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.apache.commons.logging.Log; @@ -43,9 +48,17 @@ public class MockStrategiesHelper { * @param applicationContext the application context */ public MockStrategiesHelper(ApplicationContext applicationContext) { + Assert.notNull(applicationContext, "'applicationContext' must not be null"); this.applicationContext = applicationContext; } + /** + * Returns the application context. + */ + public ApplicationContext getApplicationContext() { + return applicationContext; + } + /** * Returns a single strategy found in the given application context. * @@ -54,6 +67,7 @@ public class MockStrategiesHelper { * @throws BeanInitializationException if there is more than 1 beans of the given type */ public T getStrategy(Class type) { + Assert.notNull(type, "'type' must not be null"); Map map = applicationContext.getBeansOfType(type); if (map.isEmpty()) { return null; @@ -71,4 +85,43 @@ public class MockStrategiesHelper { } } + /** + * Returns a single strategy found in the given application context, or instantiates a default strategy if no + * applicable strategy was found. + * + * @param type the type of bean to be found in the application context + * @param defaultType the type to instantiate and return when no bean of the specified type could be found + * @return the bean found in the application context, or the default type if no bean of the given type can be found + * @throws BeanInitializationException if there is more than 1 beans of the given type + */ + public T getStrategy(Class type, Class defaultType) { + Assert.notNull(defaultType, "'defaultType' must not be null"); + T t = getStrategy(type); + if (t != null) { + return t; + } + else { + if (logger.isDebugEnabled()) { + logger.debug("No " + ClassUtils.getShortName(type) + " found, using default " + + ClassUtils.getShortName(defaultType)); + } + T defaultStrategy = BeanUtils.instantiateClass(defaultType); + if (defaultStrategy instanceof ApplicationContextAware) { + ApplicationContextAware applicationContextAware = (ApplicationContextAware) defaultStrategy; + applicationContextAware.setApplicationContext(applicationContext); + } + if (defaultStrategy instanceof InitializingBean) { + InitializingBean initializingBean = (InitializingBean) defaultStrategy; + try { + initializingBean.afterPropertiesSet(); + } + catch (Exception ex) { + throw new BeanCreationException("Invocation of init method failed", ex); + } + } + return defaultStrategy; + } + } + + } diff --git a/test/src/test/java/org/springframework/ws/test/client/MockWebServiceServerTest.java b/test/src/test/java/org/springframework/ws/test/client/MockWebServiceServerTest.java new file mode 100644 index 00000000..8dce7485 --- /dev/null +++ b/test/src/test/java/org/springframework/ws/test/client/MockWebServiceServerTest.java @@ -0,0 +1,78 @@ +/* + * Copyright 2005-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ws.test.client; + +import org.springframework.beans.factory.BeanInitializationException; +import org.springframework.context.support.StaticApplicationContext; +import org.springframework.ws.client.core.WebServiceTemplate; +import org.springframework.ws.client.core.support.WebServiceGatewaySupport; + +import org.junit.Test; + +import static org.junit.Assert.assertNotNull; + +public class MockWebServiceServerTest { + + @Test + public void createServerWebServiceTemplate() throws Exception { + WebServiceTemplate template = new WebServiceTemplate(); + + MockWebServiceServer server = MockWebServiceServer.createServer(template); + assertNotNull(server); + } + + @Test + public void createServerGatewaySupport() throws Exception { + MyClient client = new MyClient(); + + MockWebServiceServer server = MockWebServiceServer.createServer(client); + assertNotNull(server); + } + + @Test + public void createServerApplicationContextWebServiceTemplate() throws Exception { + StaticApplicationContext applicationContext = new StaticApplicationContext(); + applicationContext.registerSingleton("webServiceTemplate", WebServiceTemplate.class); + applicationContext.refresh(); + + MockWebServiceServer server = MockWebServiceServer.createServer(applicationContext); + assertNotNull(server); + } + + @Test + public void createServerApplicationContextWebServiceGatewaySupport() throws Exception { + StaticApplicationContext applicationContext = new StaticApplicationContext(); + applicationContext.registerSingleton("myClient", MyClient.class); + applicationContext.refresh(); + + MockWebServiceServer server = MockWebServiceServer.createServer(applicationContext); + assertNotNull(server); + } + + @Test(expected = BeanInitializationException.class) + public void createServerApplicationContextEmpty() throws Exception { + StaticApplicationContext applicationContext = new StaticApplicationContext(); + applicationContext.refresh(); + + MockWebServiceServer server = MockWebServiceServer.createServer(applicationContext); + assertNotNull(server); + } + + public static class MyClient extends WebServiceGatewaySupport { + + } +} diff --git a/test/src/test/java/org/springframework/ws/test/server/MockWebServiceClientTest.java b/test/src/test/java/org/springframework/ws/test/server/MockWebServiceClientTest.java new file mode 100644 index 00000000..a6f210ea --- /dev/null +++ b/test/src/test/java/org/springframework/ws/test/server/MockWebServiceClientTest.java @@ -0,0 +1,48 @@ +/* + * Copyright 2005-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ws.test.server; + +import org.springframework.context.support.StaticApplicationContext; +import org.springframework.ws.soap.saaj.SaajSoapMessageFactory; +import org.springframework.ws.soap.server.SoapMessageDispatcher; + +import org.junit.Test; + +import static org.junit.Assert.assertNotNull; + +public class MockWebServiceClientTest { + + @Test + public void createServerApplicationContext() throws Exception { + StaticApplicationContext applicationContext = new StaticApplicationContext(); + applicationContext.registerSingleton("messageDispatcher", SoapMessageDispatcher.class); + applicationContext.registerSingleton("messageFactory", SaajSoapMessageFactory.class); + applicationContext.refresh(); + + MockWebServiceClient client = MockWebServiceClient.createClient(applicationContext); + assertNotNull(client); + } + + @Test + public void createServerApplicationContextDefaults() throws Exception { + StaticApplicationContext applicationContext = new StaticApplicationContext(); + applicationContext.refresh(); + + MockWebServiceClient client = MockWebServiceClient.createClient(applicationContext); + assertNotNull(client); + } +} diff --git a/test/src/test/java/org/springframework/ws/test/support/MockStrategiesHelperTest.java b/test/src/test/java/org/springframework/ws/test/support/MockStrategiesHelperTest.java index f2b42533..6154839b 100644 --- a/test/src/test/java/org/springframework/ws/test/support/MockStrategiesHelperTest.java +++ b/test/src/test/java/org/springframework/ws/test/support/MockStrategiesHelperTest.java @@ -31,7 +31,7 @@ public class MockStrategiesHelperTest { StaticApplicationContext applicationContext = new StaticApplicationContext(); MockStrategiesHelper helper = new MockStrategiesHelper(applicationContext); - assertNull(helper.getStrategy(MyBean.class)); + assertNull(helper.getStrategy(IMyBean.class)); } @Test @@ -40,7 +40,7 @@ public class MockStrategiesHelperTest { applicationContext.registerSingleton("myBean", MyBean.class); MockStrategiesHelper helper = new MockStrategiesHelper(applicationContext); - assertNotNull(helper.getStrategy(MyBean.class)); + assertNotNull(helper.getStrategy(IMyBean.class)); } @Test(expected = BeanInitializationException.class) @@ -50,10 +50,24 @@ public class MockStrategiesHelperTest { applicationContext.registerSingleton("myBean2", MyBean.class); MockStrategiesHelper helper = new MockStrategiesHelper(applicationContext); - helper.getStrategy(MyBean.class); + helper.getStrategy(IMyBean.class); + } + + @Test + public void noneWithDefault() { + StaticApplicationContext applicationContext = new StaticApplicationContext(); + + + MockStrategiesHelper helper = new MockStrategiesHelper(applicationContext); + assertNotNull(helper.getStrategy(IMyBean.class, MyBean.class)); } - public static class MyBean { + + public interface IMyBean { + + } + + public static class MyBean implements IMyBean { }