Sunday, June 30, 2013

A Few Tricks in Writing End-to-end JAX-RS Unit Tests with Mock Objects

Lately I was helping a team migrating their spring mvc based web service to a JAX-RS based (more specifically, Jersey) implementation. When the team developed their current web services, they didn't have time to develop the end-to-end unit tests, so things could only be tested through the browser after a full deployment. It was time consuming, so the first thing I wanted to make sure when I started the migration was I should be able to unit test things end-to-end without a full deployment*. 

Jersey was designed with this in mind. You can extend your unit test from JerseyTest  and it can deploy the web resources to an embedded web container. Combined with tools like RestAssured and Mockito (or any other mocking framework), you can start an embedded grizzly container with your web resources (with JerseyTest), mock the service layer (using Mockito), and test it with real REST calls (with RestAssured).    

Things become slightly tricky when you are also using Spring. The Spring context is created and hidden inside the embedded web container**. If you need to access some Spring beans during testing, there is no easy way to get them because the Spring context is not available. One web post suggested modifying the JerseyTest and extending the container factory to provide a hook. Though this approach works***, it seems a bit too heavy to me. Is there a simpler way? 

The answer, turns out to be extremely simple if you are using Spring 3. In Spring 3, you can annotate a class with @Configuration to indicate the class will provide context configuration and handle bean creations with @Bean annotation on a static method. Since a bean can "capture" the context if it implements  the ApplicationContextAware interface, we can "capture" the context easily by adding the @Configuration annotation to the test itself and created a context holder bean, as showed in the following code snippet:   



To demonstrate how an end-to-end unit test can be developed using this technique, I wrote a sample test case which combined all the techniques mentioned in this post. You can access the code on github (https://github.com/jiunjiunma/spring-jersey-test). Had you needed to unit test your RESTful web services, these can be pretty neat tricks to add to your toolbox.


*It also gave me more confidence when I did the refactoring.

**Note when you add the @ContextConfiguration annotation with JerseyTest, a new spring context is created but is not known to the embedded web container.

***The author had made the code available. The link on the original post is broken, but you can still do a google search on the class name and find the code.