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" &gt;

Next i added my AEGISbean and JAXWS Factory Bean
&lt;bean id="aegisBean"
class="org.apache.cxf.aegis.databinding.AegisDatabinding"
scope="prototype"/&gt;
&lt;bean id="jaxwsAndAegisServiceFactory"
class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean"
scope="prototype"&gt;
&lt;property name="dataBinding" ref="aegisBean"/&gt;
&lt;property name="serviceConfigurations"&gt;
&lt;list&gt;
&lt;bean class="org.apache.cxf.jaxws.support.JaxWsServiceConfiguration"/&gt;
&lt;bean class="org.apache.cxf.aegis.databinding.AegisServiceConfiguration"/&gt;
&lt;bean class="org.apache.cxf.service.factory.DefaultServiceConfiguration"/&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/bean&gt;

Then all I had to do was declare my endpoint
&lt;jaxws:endpoint id="userServiceFactory"
implementor="#<strong>userManager</strong>"
address="/<strong>UserService</strong>"&gt;
&lt;jaxws:serviceFactory&gt;
&lt;ref bean="jaxwsAndAegisServiceFactory"/&gt;
&lt;/jaxws:serviceFactory&gt;
&lt;/jaxws:endpoint&gt;

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:

[ROOT]/pom.xml
|–>/core (jar)
|–>/webapp (war)

In my root pom.xml, I have a surefire plugin defined to seperate my unt, from functions tests

&lt;plugin&gt;
&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
&lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt;
&lt;version&gt;2.4.3&lt;/version&gt;
&lt;configuration&gt;
&lt;argLine&gt;-Xmx256m&lt;/argLine&gt;
&lt;testFailureIgnore&gt;false&lt;/testFailureIgnore&gt;

&lt;suiteXmlFiles&gt;
&lt;suiteXmlFile&gt;src/test/resources/testng.xml&lt;/suiteXmlFile&gt;
&lt;/suiteXmlFiles&gt;

&lt;excludes&gt;
&lt;exclude&gt;**/selenium/*Test.java&lt;/exclude&gt;
&lt;exclude&gt;**/*$*&lt;/exclude&gt;
&lt;/excludes&gt;
&lt;/configuration&gt;

&lt;executions&gt;
&lt;execution&gt;
&lt;id&gt;surefire-it&lt;/id&gt;
&lt;phase&gt;integration-test&lt;/phase&gt;
&lt;goals&gt;
&lt;goal&gt;test&lt;/goal&gt;
&lt;/goals&gt;
&lt;configuration&gt;
&lt;suiteXmlFiles&gt;
&lt;suiteXmlFile&gt;src/test/resources/testng-functional.xml&lt;/suiteXmlFile&gt;
&lt;/suiteXmlFiles&gt;
&lt;excludes&gt;
&lt;exclude&gt;none&lt;/exclude&gt;
&lt;/excludes&gt;
&lt;includes&gt;
&lt;include&gt;**/selenium/*Test.java&lt;/include&gt;
&lt;/includes&gt;
&lt;/configuration&gt;
&lt;/execution&gt;
&lt;/executions&gt;
&lt;/plugin&gt;

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 --> &lt;bean id="userClientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean"&gt;
&lt;property name="serviceClass" value="com.baselogic.service.UserManager"/&gt;
&lt;property name="address"
value="${test.application.address}/cxf/UserService"/&gt;
&lt;property name="serviceFactory" ref="jaxwsAndAegisServiceFactory"/&gt;
&lt;/bean&gt;

&lt;bean id="userClient"
class="com.baselogic.service.impl.UserManagerImpl"
factory-bean="userClientFactory"
factory-method="create"/&gt;

Then I can run my test runs as expected

Mick Knutson

Java, JavaEE, J2EE, WebLogic, WebSphere, JBoss, Tomcat, Oracle, Spring, Maven, Architecture, Design, Mentoring, Instructor and Agile Consulting. http://www.baselogic.com/blog/resume

View all posts

Java / JavaEE / Spring Boot Channel

BLiNC Supporters

BLiNC Adsense

Archives

Newsletter