So after an entire weekend of frustration with tutorials such as http://xfire.codehaus.org/JSR+181+Annotations and http://docs.codehaus.org/pages/viewpage.action?pageId=44565 I think I have come up with a way to test XFire services deployed through Tomcat during my Maven build.
So I created an annotated version of an Echo Service:
package com.baselogic.service;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
@WebService(name = "EchoService",
targetNamespace = "http://service.baselogic.com")
public interface EchoService {
@WebMethod(operationName = "echoString", action = "urn:EchoString")
@WebResult(name = "echoResult", targetNamespace = "http://service.baselogic.com")
public String echoString(
@WebParam(name = "echoParam", targetNamespace = "http://service.baselogic.com", header = true)
String echoParam);
}Then created my implementation class:
package com.baselogic.service;
import javax.jws.WebService;
/**
* Echo XFire Web Service
*/
@WebService(serviceName = "Echo",
targetNamespace = "http://service.baselogic.com", endpointInterface = "com.baselogic.service.EchoService")
public class EchoImpl implements EchoService {
public String echoString(String input) {
return "Echo Response: " + input;
}
}I then created a /WEB-INF/xfire-servlet.xml resource that only contains the following mappings:
class="org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations"/> class="org.codehaus.xfire.annotations.AnnotationServiceFactory"> com.baselogic.service.EchoService
In my web.xml, I added my xfire-servlet.xml:
contextConfigLocation classpath:/applicationContext-resources.xml classpath:/applicationContext-service.xml classpath:org/codehaus/xfire/spring/xfire.xml /WEB-INF/xfire-servlet.xml
I added my xfire spring servlet:
xfire org.codehaus.xfire.spring.XFireSpringServlet
Now I kept seeing several JUnit examples with many convenience methods, but I wanted to use TestNG instead. So I created a testng-functional.xml file with some parameters that I needed.
Then I used those in my TestNG test like:
package com.baselogic.service;
import com.baselogic.service.impl.UserManagerImpl;
import com.baselogic.util.StringUtil;
import com.baselogic.domain.User;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
import org.codehaus.xfire.XFire;
import org.codehaus.xfire.XFireFactory;
import org.codehaus.xfire.aegis.AegisBindingProvider;
import org.codehaus.xfire.annotations.AnnotationServiceFactory;
import org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations;
import org.codehaus.xfire.client.XFireProxyFactory;
import org.codehaus.xfire.service.Service;
import org.codehaus.xfire.service.ServiceRegistry;
import org.codehaus.xfire.xmlbeans.XmlBeansTypeRegistry;
import org.testng.AssertJUnit;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
import java.net.MalformedURLException;
import java.net.URL;
public class UserServiceTest {
// configure log4j
static {
URL log4j = Thread.currentThread().getContextClassLoader().getResource(
"log4j.xml");
DOMConfigurator.configure(log4j);
}
protected Logger log = Logger.getLogger(getClass());
protected String echoUrl = "http://localhost:8080/services/Echo";
protected String serviceUrlLocal;
Service serviceModel;
AnnotationServiceFactory factory;
ServiceRegistry serviceRegistry;
XFire xfire;
@Parameters({"serviceUrlLocal"})
@BeforeClass(groups = {"functional"})
protected void init(String serviceUrlLocal) throws Exception {
log.info("Setup XFire Registry");
this.serviceUrlLocal = serviceUrlLocal;
xfire = XFireFactory.newInstance().getXFire();
AnnotationServiceFactory factory = new AnnotationServiceFactory(new Jsr181WebAnnotations(),
xfire.getTransportManager(),
new AegisBindingProvider(new XmlBeansTypeRegistry()));
serviceModel = factory.create(UserManagerImpl.class);
xfire.getServiceRegistry().register(serviceModel);
serviceRegistry = xfire.getServiceRegistry();
serviceRegistry.register(serviceModel);
}
@AfterClass(groups = {"functional"})
protected void stop() throws Exception {
log.info("Stopping XFire Registry");
xfire.getServiceRegistry().unregister(serviceModel);
}
@Test(groups = {"functional"})
public void testGetUser() throws Exception {
XFireProxyFactory xFireProxyFactory = new XFireProxyFactory(xfire);
UserManager userManager = null;
User user = null;
try {
userManager = (UserManager) xFireProxyFactory.create(serviceModel, serviceUrlLocal);
user = userManager.getUser("mknutson");
AssertJUnit.assertNotNull(user.getUsername());
AssertJUnit.assertEquals("mknutson", user.getUsername());
} catch (MalformedURLException e) {
log.debug("WsClient.callWebService(): EXCEPTION: " + e.toString());
}
catch (Exception e) {
e.printStackTrace();
throw e;
}
}
}The difference I found out that was different in testNG from the examples I saw, was the use of a local URL verse the full service url. I could never get the full url o work, but I assume that the JUnit helper classes from xfire resolve that url to a local anyways. When I changed to the local url, my service started working fine. I later removed the serviceUrl parameter later and just used the serviceUrlLocal parameter for my tests going forward.

