REST-assured vs Jersey-Test-Framework: Testing your RESTful Web-Services
September 5th, 2011 by micha kops
Today we’re going to take a look at two specific frameworks that enables you to efficiently test your REST-ful services: On the one side there is the framework REST-assured that offers a nice DSL-like syntax to create well readable tests – on the other side there is the Jersey-Test-Framework that offers a nice execution environment and is built upon the JAX-RS reference implementation, Jersey.
In the following tutorial we’re going to create a simple SOAP service first and then implement integration tests for this service using both frameworks.
The title of this article might be misleading due to the fact that I am not going to compare both frameworks to choose a winner, just showing the different approach ..
Contents
Prerequisites
Only JDK and Maven needed here …
Creating a new Maven project
A new Maven project is our first step for the following tutorial ..
- Create a new Maven project with your favourite IDE and Maven plugin installed or via console using
mvn archetype:generate
- That’s all for now
The REST Service to be tested
First we need a REST service to write some tests for .. luckily that’s done with a few steps using JAX-RS ..
- First we’re adding some dependencies for Jersey, JAX-B and Jersey-JSON to our pom.xml
<dependencies> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-server</artifactId> <version>1.9</version> </dependency> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.2.4</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>2.2.4</version> </dependency> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-core</artifactId> <version>1.9</version> </dependency> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-json</artifactId> <version>1.9</version> </dependency> </dependencies> <repositories> <repository> <id>maven2-repository.dev.java.net</id> <name>Java.net Repository for Maven</name> <url>http://download.java.net/maven/2/</url> <layout>default</layout> </repository> <repository> <id>maven-repository.dev.java.net</id> <name>Java.net Maven 1 Repository (legacy)</name> <url>http://download.java.net/maven/1</url> <layout>legacy</layout> </repository> </repositories>
- In the next step we’re creating our exported service method in a class named UserService
package com.hascode.tutorial.rest; import java.util.Date; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @Path("/user") public class UserService { @GET @Produces(MediaType.APPLICATION_JSON) @Path("/id/{id}") public User findById(@PathParam("id") final Long id) { if (id.equals(666l)) { return null; } final User user = new User(); user.setId(id); user.setFirstName("Tim"); user.setLastName("Tester"); user.setBirthday(new Date(1321009871)); return user; } }
- The service exports a User object as a JSON structure .. this is done via @Produces(MediaType.APPLICATION_JSON)
- Now we need the user object .. the mapping to JSON is done using JAX-B – the only thing we need is one annotation, @XmlRootElement
package com.hascode.tutorial.rest; import java.util.Date; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class User { private Long id; private String firstName; private String lastName; private Date birthday; // getter + setter }
- Finally we’re adding the following web.xml to the directory src/main/webapp/WEB-INF
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <servlet> <servlet-name>Jersey REST Servlet</servlet-name> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> <init-param> <param-name>com.sun.jersey.config.property.packages</param-name> <param-value>com.hascode.tutorial.rest</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Jersey REST Servlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
- Now we’re starting the rest service with an embedded tomcat instance using
mvn tomcat:run
- We’re able to run the REST service by calling the following url http://localhost:8080/rest-test-tutorial/user/id/12
- The service returns the following JSON code
{ "birthday":"1970-01-16T07:56:49.871+01:00", "firstName":"Tim", "id":"12", "lastName":"Tester" } - Keep the embedded tomcat process running .. we’re going to need it for our integration tests later ..
Testing the Service
Now that we’ve got a nice, running REST service we want to test the exported service methods and data we’re getting from the service..
Using REST-assured
The first candidate for writing an integration test here is REST-assured ….
- First we’re adding the dependencies for the REST-assured framework to our pom.xml
<dependency> <groupId>com.jayway.restassured</groupId> <artifactId>rest-assured</artifactId> <version>1.2.3</version> </dependency>
- That’s what our integration test looks like
package com.hascode.tutorial.rest; import static com.jayway.restassured.RestAssured.expect; import static com.jayway.restassured.RestAssured.get; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.nullValue; import org.junit.Test; public class UserServiceTestUsingRestAssured { @Test public void testUserFetchesSuccess() { expect(). body("id", equalTo("12")). body("firstName", equalTo("Tim")). body("lastName", equalTo("Tester")). body("birthday", equalTo("1970-01-16T07:56:49.871+01:00")). when(). get("/rest-test-tutorial/user/id/12"); } @Test public void testUserNotFound() { expect(). body(nullValue()). when(). get("/rest-test-tutorial/user/id/666"); } }
- For more detailed information on the testing and matcher api, take a look at the documentation on the rest-assured website
- That what my JUnit Runner in Eclipse looks like


- *Update:* I have written a complete and detailed tutorial covering the different features of the REST-assured framework and added a RESTful web service to run the tests from the tutorial against it: “Testing RESTful Web Services made easy using the REST-assured framework”
Using Jersey-Test-Framework
Now let’s try Jersey ..
- We need some dependencies for the jersey-test-framework so we’re adding them to our pom.xml
<dependency> <groupId>com.sun.jersey.jersey-test-framework</groupId> <artifactId>jersey-test-framework-core</artifactId> <version>1.9</version> <scope>test</scope> </dependency> <dependency> <groupId>com.sun.jersey.jersey-test-framework</groupId> <artifactId>jersey-test-framework-external</artifactId> <version>1.9</version> </dependency>
- That’s how our integration test looks like
package com.hascode.tutorial.rest; import static org.junit.Assert.assertEquals; import java.net.URISyntaxException; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import org.junit.Test; import com.sun.jersey.api.client.UniformInterfaceException; import com.sun.jersey.api.client.WebResource; import com.sun.jersey.test.framework.AppDescriptor; import com.sun.jersey.test.framework.JerseyTest; import com.sun.jersey.test.framework.WebAppDescriptor; public class UserServiceTestUsingJerseyTestFramework extends JerseyTest { @Override protected AppDescriptor configure() { return new WebAppDescriptor.Builder().build(); } @Test public void testUserFetchesSuccess() throws JSONException, URISyntaxException { WebResource webResource = client().resource("http://localhost:8080/"); JSONObject json = webResource.path("/rest-test-tutorial/user/id/12") .get(JSONObject.class); assertEquals("12", json.get("id")); assertEquals("Tim", json.get("firstName")); assertEquals("Tester", json.get("lastName")); assertEquals("1970-01-16T07:56:49.871+01:00", json.get("birthday")); } @Test(expected = UniformInterfaceException.class) public void testUserNotFound() { WebResource webResource = client().resource("http://localhost:8080/"); JSONObject json = webResource.path("/rest-test-tutorial/user/id/666") .get(JSONObject.class); } }
- More detailed information on the jersey-test-framework can be found at its project website or Naresh’ blog. The real strength of the Jersey-Test-Framework lies in its capability to start different types of containers to create a test environment for your rest service – we don’t use this nice feature here and could have also simply created a Jersey client using Client client = Client.create() and parsed the response …
- Running the sample code in your IDE your JUnit view might look like this one

Tutorial Sources
I have put the source from this tutorial on my Bitbucket repository – download it there or check it out using Mercurial:
hg clone https://bitbucket.org/hascode/hascode-tutorials
Troubleshooting
- “Caused by: com.sun.jersey.api.MessageException: A message body writer for Java class …, and Java type class…, and MIME media type application/json was not found” – The dependency for jersey-json is missing .. just add the following dependency to your pom.xml
<dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-json</artifactId> <version>1.9</version> </dependency>
Resources
- Johan Haleby: REST Assured – Or how to easily test REST services in Java
- REST-assured Project Website
- REST Assured JavaDocs
- Jersey Test Framework JavaDocs
- REST-assured examples
- Jersey User Guide: Jersey Test Framework
Tags: hamcrest, integrationtest, jax-b, jax-rs, jaxb, jersey, junit, rest, rest-assured, restful, service, test
September 15th, 2011 at 5:22 pm
Great blog post! As the founder of REST Assured I just want to point out that the real benefit of this framework comes to light when we’re doing a bit more complicated tests. It’s very simple to do e.g. authentication, file uploading, re-use of specifications across multiple tests and its ability to use Groovy lambda expressions when validating complex JSON or XML documents. I’ll hopefully blog about the latter in a not so distance future.
Regards,
/Johan
September 15th, 2011 at 6:27 pm
thanks! i’ve fallen in love with this framework in one project where I had to write excessive tests for several RESTful webservices delivering JSON and XML. rest-assured made my day(s)
i am planning to write another article with some examples that have helped me a lot in the past.
Please keep up the great work with rest-assured (and of course powermock!)
October 31st, 2011 at 11:08 pm
Hi,
I was using JerseyTest for the REST testing but want to shift to Rest assured but i am getting a few issues.
Running Jersey Test was done by
mvn clean install ;
The above will compile the code, run the tests in the embedded grizzly container, and run the tests.
However for RESTAssured, i need to start the server and then run tests from eclipse, which is not something i want to do, the reason being that there are some reports of code coverage etc generated which are dependent on the tests which are run, and so i want it to be part of the build.
But if i just try to run “mvn clean install”, RESTAssured tries to find the server at localhost:8080, and fails.
Is there a way to accomplish it?
Thanks
December 2nd, 2011 at 12:16 pm
Hi,
When I am trying to build the above example I am getting compilation failure, I am using maven 2 and open jdk 1.6
INFO] ————————————————————————
[ERROR] BUILD FAILURE
[INFO] ————————————————————————
[INFO] Compilation failure
/NotBackedUp/ldash/software/Rest-assured/rest-test-tutorial/src/main/java/com/hascode/tutorial/rest/UserService.java:[11,1] annotations are not supported in -source 1.3
(use -source 5 or higher to enable annotations)
@Path(“/user”)
/NotBackedUp/ldash/software/Rest-assured/rest-test-tutorial/src/main/java/com/hascode/tutorial/rest/User.java:[7,1] annotations are not supported in -source 1.3
(use -source 5 or higher to enable annotations)
@XmlRootElement
[INFO] ————————————————————————
[INFO] Trace
org.apache.maven.BuildFailureException: Compilation failure
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:715)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle(DefaultLifecycleExecutor.java:556)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:535)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:387)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:348)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:180)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:328)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:138)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:362)
at org.apache.maven.cli.compat.CompatibleMain.main(CompatibleMain.java:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
Caused by: org.apache.maven.plugin.CompilationFailureException: Compilation failure
at org.apache.maven.plugin.AbstractCompilerMojo.execute(AbstractCompilerMojo.java:516)
at org.apache.maven.plugin.CompilerMojo.execute(CompilerMojo.java:114)
at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:490)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:694)
… 17 more
[INFO] ————————————————————————
[INFO] Total time: 2 minutes 19 seconds
[INFO] Finished at: Fri Dec 02 16:57:09 IST 2011
[INFO] Final Memory: 22M/167M
December 2nd, 2011 at 12:17 pm
Hi,
When I am trying to build the above example I am getting compilation failure, I am using maven 2 and open jdk 1.6. Could you please have a look at it let me know where is the problem.
Thanks in advance
INFO] ————————————————————————
[ERROR] BUILD FAILURE
[INFO] ————————————————————————
[INFO] Compilation failure
/NotBackedUp/ldash/software/Rest-assured/rest-test-tutorial/src/main/java/com/hascode/tutorial/rest/UserService.java:[11,1] annotations are not supported in -source 1.3
(use -source 5 or higher to enable annotations)
@Path(“/user”)
/NotBackedUp/ldash/software/Rest-assured/rest-test-tutorial/src/main/java/com/hascode/tutorial/rest/User.java:[7,1] annotations are not supported in -source 1.3
(use -source 5 or higher to enable annotations)
@XmlRootElement
[INFO] ————————————————————————
[INFO] Trace
org.apache.maven.BuildFailureException: Compilation failure
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:715)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle(DefaultLifecycleExecutor.java:556)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:535)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:387)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:348)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:180)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:328)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:138)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:362)
at org.apache.maven.cli.compat.CompatibleMain.main(CompatibleMain.java:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
Caused by: org.apache.maven.plugin.CompilationFailureException: Compilation failure
at org.apache.maven.plugin.AbstractCompilerMojo.execute(AbstractCompilerMojo.java:516)
at org.apache.maven.plugin.CompilerMojo.execute(CompilerMojo.java:114)
at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:490)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:694)
… 17 more
[INFO] ————————————————————————
[INFO] Total time: 2 minutes 19 seconds
[INFO] Finished at: Fri Dec 02 16:57:09 IST 2011
[INFO] Final Memory: 22M/167M
December 2nd, 2011 at 12:37 pm
You should advise maven to use Java 6 .. just add the following snippet to you pom.xml:
<plugins><plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
December 2nd, 2011 at 3:01 pm
Hey Micha it works for me now thanks a lot man.
December 2nd, 2011 at 4:09 pm
Now while trying to run the test case from eclipse I am getting the following error
java.lang.NoClassDefFoundError: groovyx/net/http/HTTPBuilder
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2444)
at java.lang.Class.getDeclaredMethods(Class.java:1808)
I have added all the necessary jar in the build path (groovy1.7.11.jar,junit.jar ,rest-assured-1.4.jar etc),Please suggest what could be the problem.
December 3rd, 2011 at 4:30 pm
Do you have the Maven Plugin for Eclipse installed? And if so – is your project “mavenized”?
December 4th, 2011 at 12:26 pm
yes I am having the maven plugin for eclipse but I was building the war file(for rest service) from command prompt through “mvn clean install”, and for testing the functionality I was running the test case from eclipse.
And when I am trying to run the test from command prompt using “mvn -Dtest=UserServiceTestUsingRestAssured test” I am getting the following error
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.073 sec <<< FAILURE!
testUserFetchesSuccess(com.hascode.tutorial.rest.UserServiceTestUsingRestAssured) Time elapsed: 0.055 sec <<< ERROR!
java.lang.NoClassDefFoundError: antlr/collections/AST
at org.codehaus.groovy.antlr.AntlrParserPluginFactory.createParserPlugin(AntlrParserPluginFactory.java:27)
at org.codehaus.groovy.control.SourceUnit.parse(SourceUnit.java:234)
at org.codehaus.groovy.control.CompilationUnit$1.call(CompilationUnit.java:157)
December 5th, 2011 at 9:44 am
Hi Micha please ignore my previous messages, Now I have “Mavenized” my project it’s working fine.
December 5th, 2011 at 1:48 pm
But when I am trying to ran the test cases from Linux I am getting the following error
estUserFetchesSuccess(com.hascode.tutorial.rest.UserServiceTestUsingRestAssured) Time elapsed: 0.153 sec <<< ERROR!
java.lang.NoClassDefFoundError: org/objectweb/asm/Opcodes
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:634)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:277)
at java.net.URLClassLoader.access$000(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:212)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
and testUserNameNotFound(com.hascode.tutorial.rest.UserServiceTestUsingRestAssured) Time elapsed: 0 sec <<< ERROR!
java.lang.NoClassDefFoundError: Could not initialize class com.jayway.restassured.RestAssured
at com.hascode.tutorial.rest.UserServiceTestUsingRestAssured.testUserNameNotFound(UserServiceTestUsingRestAssured.java:52)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Do I need to change something on pom file for groovy and rest-assured?
December 6th, 2011 at 7:45 pm
org.objectweb.asm.Opcodes is included twice .. one is in the “rest-assured” lib .. it’s asm:asm:3.2 .. in the dependency for “jersey-server” there’s also a dependency to the asm lib (asm:asm:3.1) so the class should definitely be there .. but I think the two dependencies are the reason that asm-3.1 is used .. perhaps you can resolve the error by fixing the version by exclusion in your pom.xml
And if you’re using rest-assured solely .. please take a look at the following tutorial of mine
December 7th, 2011 at 4:48 am
Thanks for the reply, I have gone through your tutorial,It’s really a good one