I converted from XFire to CXF which is really XFire 2 I guess. Now I am using Maven, DBUnit, TestNG, H2 and embedded Tomcat for continuous integration testing. Now I wanted to be able to test my webservice contracts as well, and Spring has helped me to accomplish that.
In my webservices war, I first added the required name spaces to my webapp.war::/WEB-INF/applicationContext.xml and add the cxf imports as well as configure logging.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:cxf="http://cxf.apache.org/core" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd <strong>http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd</strong> <strong>http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"</strong> default-autowire="byName" default-lazy-init="false" >
Next i added my AEGISbean and JAXWS Factory Bean
<bean id="aegisBean" class="org.apache.cxf.aegis.databinding.AegisDatabinding" scope="prototype"/> <bean id="jaxwsAndAegisServiceFactory" class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean" scope="prototype"> <property name="dataBinding" ref="aegisBean"/> <property name="serviceConfigurations"> <list> <bean class="org.apache.cxf.jaxws.support.JaxWsServiceConfiguration"/> <bean class="org.apache.cxf.aegis.databinding.AegisServiceConfiguration"/> <bean class="org.apache.cxf.service.factory.DefaultServiceConfiguration"/> </list> </property> </bean>
Then all I had to do was declare my endpoint
<jaxws:endpoint id="userServiceFactory" implementor="#<strong>userManager</strong>" address="/<strong>UserService</strong>"> <jaxws:serviceFactory> <ref bean="jaxwsAndAegisServiceFactory"/> </jaxws:serviceFactory> </jaxws:endpoint>
Note that #userManager is out of my core.jar::/META-INF/applicationResources-service.xml and I wanted to expose the service as /UserService
I use cargo to deploy my webapp.war to an embeded tomcat. Once deployed, I have TestNG run my functional tests to test the deployed service.
So first, I have a Maven multi-module project such as:
|–>/core (jar)
|–>/webapp (war)
In my root pom.xml, I have a surefire plugin defined to seperate my unt, from functions tests
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.4.3</version> <configuration> <argLine>-Xmx256m</argLine> <testFailureIgnore>false</testFailureIgnore> <suiteXmlFiles> <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile> </suiteXmlFiles> <excludes> <exclude>**/selenium/*Test.java</exclude> <exclude>**/*$*</exclude> </excludes> </configuration> <executions> <execution> <id>surefire-it</id> <phase>integration-test</phase> <goals> <goal>test</goal> </goals> <configuration> <suiteXmlFiles> <suiteXmlFile>src/test/resources/testng-functional.xml</suiteXmlFile> </suiteXmlFiles> <excludes> <exclude>none</exclude> </excludes> <includes> <include>**/selenium/*Test.java</include> </includes> </configuration> </execution> </executions> </plugin>
In the integration-test phase, TestNG run the following test:
public class UserWebServiceTest extends AbstractSpringTest { protected Logger log = Logger.getLogger(getClass()); @Test(groups = {"functional"}) public void testGetUser() throws Exception { log.debug("testGetUser"); UserManager userManager = (UserManager) applicationContext.getBean("userClient"); User user = userManager.getUser("-1"); Address address = user.getAddress(); Assert.assertNotNull(user.getUsername()); Assert.assertEquals("mickknutson", user.getUsername()); Assert.assertEquals("Mick", user.getFirstName()); Assert.assertEquals("Knutson", user.getLastName()); } @Test(groups = {"functional"}, expectedExceptions = UserNotFoundException.class) public void testGetInvalidUser() throws Exception { log.debug("testGetInvalidUser"); UserManager userManager = (UserManager) applicationContext.getBean("userClient"); User user = userManager.getUser("-99"); assert false; //shouldn't be invoked } }
Which extends my AbstractSpringTest
package com.baselogic.test; ...imports... @ContextConfiguration( locations = {"classpath:applicationContext-test.xml"} ) public abstract class AbstractSpringTest extends AbstractTestNGSpringContextTests implements InitializingBean { // configure log4j static { URL log4j = Thread.currentThread().getContextClassLoader().getResource( "log4j.xml"); DOMConfigurator.configure(log4j); } public static Logger log = Logger.getLogger(AbstractHibernateTest.class); public AbstractSpringTest() { super(); } //=======================================================================// //===== Start the Inherited Test ========================================// //=======================================================================// @BeforeMethod(groups = "database") public void beforeTestMethod() throws Exception { log.debug("Invoked beforeTestMethod()"); } @AfterMethod(groups = "database") public void afterTestMethod() throws Exception { log.debug("Invoked afterTestMethod()"); } /** (non-Javadoc) * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() */ public void afterPropertiesSet() throws Exception { if (this.applicationContext == null) throw new IllegalStateException("applicationContext is null"); } }
Then in my src/test/resources/applicationResources-test.xml I only have to declare the factory and dynamic proxy for the client
<!-- Factory to create the dynamic proxy --> <bean id="userClientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean"> <property name="serviceClass" value="com.baselogic.service.UserManager"/> <property name="address" value="${test.application.address}/cxf/UserService"/> <property name="serviceFactory" ref="jaxwsAndAegisServiceFactory"/> </bean> <bean id="userClient" class="com.baselogic.service.impl.UserManagerImpl" factory-bean="userClientFactory" factory-method="create"/>
Then I can run my test runs as expected
Recent Comments