Unit Testing Spring Jersey Integration

Recently, I’ve been working on a side project which has given me the opportunity to play with an interesting Java technology stack. After a few weekends of working on the build and moving my way up the stack from database to service layer I was at the point of writing a full integration test. In the past I’ve done integration testing with an iBatis/Spring stack, which, with the help of DBUnit is a fairly simple exercise. However, this project is heavily REST based and the addition of Jersey (JAX-RS) was a serious curveball.

To really test the whole stack an embedded webserver is required.  Looking through the Jersey/Spring unit tests they make use of an exploded WAR using Glassfish.  Assuming this was the optimal solution I added Glassfish to my ivy.xml config and ran an ivy update.  However, once I realized the overwhelming volume of jars being downloaded I decided it was much too heavy weight of a solution.

My next choice was Jetty.  I have had experience with using Jetty in the past but I quickly ran into issues trying to get it working right with Jersey, Spring, and an exploded WAR configuration.  It was then that I saw the GrizzlyServerFactory referenced in another Jersey unit test.  After some prodding and reading into the source code I ended up with the following:

final URI baseUri = UriBuilder.fromUri( "http://localhost/" ).port( 9998 ).build();
final ServletAdapter adapter = new ServletAdapter();
adapter.addInitParameter( "com.sun.jersey.config.property.packages", <your-package-name> );
adapter.addContextParameter( "contextConfigLocation","classpath:applicationContext.xml" );
adapter.addServletListener( "org.springframework.web.context.ContextLoaderListener" );
adapter.setServletInstance( new SpringServlet() );
adapter.setContextPath( baseUri.getPath() );
SelectorThread threadSelector = GrizzlyServerFactory.create( baseUri, adapter );

We start by making a base Uri for localhost at a high numbered port.  Then we build the Grizzly ServletAdaptor.  The first parameter is the package name where your Jersey enabled are located.  The next two lines are taken directly from the web.xml file that is used for the actual WAR.  The first is the config location for the Spring Context and the second is the ContextLoaderListener servlet.  Finally we add the Jersey SpringServlet and the context path.  With these two objects created we can build a SelectorThread and begin using the server using the Jersey Client api that I talked about in my previous post.  When you are done, don’t forget to call stopEndpoint() on the SelectorThread when you are done.

EDIT:

I’ve recently come across one additional helpful tip regarding this setup. If you need to get access to your ApplicationContext, for instance to get access to the spring managed DataSource for database testing, there is a simple but non obvious way of doing this. The simple part is using Spring’s built in utilities for getting the application from a ServletContext.


WebApplicationContextUtils.getWebApplicationContext( adapter.getServletInstance().getServletConfig().getServletContext() );

However, when I first tried this I got an unexplained null pointer exception. After a long while trying to google around for the answer I gave up and dug into the source code. Turns out you need to add one important property to the ServletAdaptor for this to all work.


adapter.setProperty( "load-on-startup", 1 );

This will force your adaptor to initialize the servlet immediately and you populate the ServletConfig and ServletContext so you can get the ApplicationContext from them.

Groovin' Up Your Database Tests

While TDD proclaims the gospel of fine grained tests and a healthy dose of mock objects, at some point, interaction with a database becomes inevitable.  Luckily, there is DbUnit to assist us.  DbUnit is a fantastic framework which allows for painless setup of database data sets, ensuring repeatable, self contained unit tests. However, there are already plenty of tutorials on the subject.  Instead, what I want to talk about is the dark side of dbunit… xml.

Using dbunit on any reasonably sized project ends up with an explosion of xml data set files, even if care is taken to factor out common data sets and reuse them when possible.  For the longest time this seemed an unfortunate but necessary evil of using such an amazingly useful library, but that was before I attended the Northeast No Fluff Just Stuff in April.  Before that point I had been interested in Groovy and was looking for places to add it to our code base (actually snuck it into a script that ran in the build) but I hadn’t really pondered the possibilities it provided.  However, NFJS was over flowing with talks and general love for Groovy.  Somewhere between the Groovy unit testing and the Groovy MOP talks it dawned on me.  Why not inline the xml using a Groovy builder?!

Groovy has this fantastic feature called builders which allows for very compact syntax to generate any sort of markup (html, xml, java swing, etc).  Of course the one we want to focus on is the xml builder.  By simply changing the file extension from .java to .groovy on the unit test we are already half way there.  After using Groovy’s syntax for creating xml we simply call .toString() on the underlying writer, wrap it in a new StringReader() and then pass create a new FlatXmlDataSet() with the reader as the only constructor argument.

If you are using Ant for your build you can simply wire up the groovyc task to compile all of your groovy tests and then call junit on the .class files.  If you want to get this working in Eclipse, best of luck, I was able to kinda get it working under windows xp but now that I have switched to os x the groovy plugin screams bloody murder with 64-bit java under os x in Eclipse.

Follow

Get every new post delivered to your Inbox.