Unit testing with XFire – How to test your SOAP server with a WSDL file

6

XFire is a java SOAP framework. Of course there is Axis, but I think XFire can replace Axis. Axis is quite a good framework, but I think XFire is easier to use and performs better. We needed to provide a WSDL file to one of our customers, that customer would then implement the web service and now we talk to that web service. The beauty of the web service is that we have no idea what’s happening at the server of the customer, someone might even be typing Xml documents and sends them to us. WSDL is one of the few standards that really works.

Creating a WSDL file manually is a tedious job. There are actually people that think creating a WSDL file manually is faster than letting Axis or XFire create it for you. So when I was asked to deliver a WSDL file I created an XFire project, wrote a java interface and some config files and the job was done.
The next step was creating a unit test for the web service, that’s what this article is about.

When you’re new to XFire it’s a good idea to have a look at the the quick start guide. This guide is pretty good, so I decided not to write a getting started guide on this blog. After you read the quick start guide everything else you’ll read here should be clear. Also take a look at this article at JavaWorld, that article helped me a lot.
....

The test web service

For this article I created a ping/pong web service. You invoke the ping method and will receive pong. My project is called xfire-test, I have an interface (nl.amis.ITestService) and a class (nl.amis.TestService)

package nl.amis;


public interface ITestService {

    public String ping();

}


package nl.amis;

public class TestService implements ITestService {

    public String ping() {

        return "pong";

    }

}

My services.xml contains one entry:

<beans xmlns="http://xfire.codehaus.org/config/1.0">

    <service>

        <name>test</name>

        <namespace>amis</namespace>

        <serviceClass>nl.amis.ITestService</serviceClass>

        <implementationClass>nl.amis.TestService</implementationClass>

    </service>

</beans>

Run the webservice server in Eclipse

I use Eclipse for my unit testing and run a Tomcat servce inside Eclipse. First shut down Eclipse and include the following dependency in Maven2:

  <dependency>

    <groupId>org.codehaus.xfire</groupId>

    <artifactId>xfire-all</artifactId>

    <version>1.0</version>

  </dependency>

You also can include the XFire libraries manually of course.

To enable ‘web things’ on your project execute the following maven command:
mvn eclipse:eclipse –Dwtpversion=1.0

When you reload your Eclipse you’ll see a little earth icon on your project. You now have a dynamic web project, congratulations!

Right click on you project and choose ‘Run As’, ‘Run on server’. You might have to change some settings and include you favorite web container. In the end you should see a window that looks like this:

When you followed the quick start guide a WSDL should be available at
http://localhost:8080/xfire-test/services/test?wsdl (test this in your web browser, a chaotic xml file will appear)

First unit test

Now your web service is running in your browser and it’s time to unit test it
Create a test with the following code:

Client client = new Client(new URL("http://localhost:8080/xfire-test/services/test?WSDL"));

Object[] results = client.invoke("ping", null);

assertEquals("pong", results[0]);

Client is a org.codehaus.xfire.client.Client object (when you have to choose between different Client objects)

Second unit test

This test method works, but if you use a little more complex code you can test a lot more and talking to an interface is better than including the method you want to invoke as a string.

The second test:

Service serviceModel = new ObjectServiceFactory().create(ITestService.class);


XFire xfire = XFireFactory.newInstance().getXFire();

XFireProxyFactory factory = new XFireProxyFactory(xfire);


String serviceUrl = "http://localhost:8080/xfire-test/services/test";

ITestService client = null;


client = (ITestService) factory.create(serviceModel, serviceUrl);


assertEquals("pong", client.ping());

You can invoke a method on the client object and XFire makes sure the SOAP call is executed. When your client returns a proprietary object you’ll even receive that object (given that you have they class for the object locally)

When your webservice throws an exception you can even catch that. But there is a little catch. When an exception is thrown a XFire exception is thrown with your own exception wrapped into it.

Conclusion

Unit testing a SOAP webservice is quite easy. But this method can also be used to create a client or only a WDSL file. The only drawback is that you still need the java Interface and
the webservice’s proprietary objec
ts. The nice thing of a webservice is that you don’t know whether you’re talking to Java, .NET, Ruby, Python or a Killer Coding Ninja Monkey

XFire is integrated in the Spring framework and when you follow the Codehaus Spring Remoting manual you won’t even notice you’re using a webservice, it just looks like a local method call.

Share.

About Author

6 Comments

  1. You can only invoke a document/literal web service using XFire. I guess you have to use Axis or JDeveloper created stub for accessing a RPC/encoded web service.

  2. Client client = new Client(new URL(“http://localhost:8080/xfire-test/services/test?WSDL”));

    Object[] results = client.invoke(“ping”, null);

    assertEquals(“pong”, results[0]);

    ——————————————————————————–
    how about the return type is complex and using Dynamic Client ?
    I tried,it returned the Document object of apache.
    What should I do if I want to call a webservice existing under jdk1.4 ?
    thanks a lot

  3. Jeroen van Wilgenburg on

    I haven’t checked it out. The deep integration isn’t necessarily a requirement, usually you just want simple access to a web service.

    Thanks for the tip, I will check JAX-WS out, maybe it’s an even better library than XFire.

  4. Jeroen van Wilgenburg on

    Assume client.ping() in the example returns a complex object called ComplexObject. You have to have the class for your object locally and then it’s just
    ComplexObject result=client.ping() instead of String result=client.ping();

  5. how do i do unit testing if the return type is Complex and not simple? can we do the same thing in axis..m just curious