Test Jersey Rest Service with JUnit

In this example we show you how to test Jersey Rest Services with JUnit. JerseyTest is developed by Jersey themselves in order to facilitate the testing of their rest services. You can really easily test your services against a set of preconfigured containers or even an external container. In this tutorial we’ll focus on a preconfigured container, namely jetty.

Maven dependencies

Here is the pom.xml file I used in order to configure jersey, junit and jetty. Also a cool feature is that we can run these unit tests in parallel which leads to better performance when dealing with many unit tests. We also use the maven-war-plugin to tell maven not to fail over the missing web.xml file. Because we don’t need it for this application.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                             http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.memorynotfound.webservice.rs.jersey</groupId>
    <artifactId>unit-test-junit</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>JERSEY - ${project.artifactId}</name>
    <url>http://memorynotfound.com</url>


    <properties>
        <jersey.version>2.22.1</jersey.version>
        <junit.version>4.12</junit.version>
        <surefire.version>2.19</surefire.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet</artifactId>
            <version>${jersey.version}</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-jackson</artifactId>
            <version>${jersey.version}</version>
        </dependency>

        <!-- testing -->
        <dependency>
            <groupId>org.glassfish.jersey.test-framework.providers</groupId>
            <artifactId>jersey-test-framework-provider-jetty</artifactId>
            <version>${jersey.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${surefire.version}</version>
                <configuration>
                    <parallel>methods</parallel>
                    <threadCount>10</threadCount>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

Example Jersey Rest Service

This jersey rest service is a simple example to explain the common HTTP Methods used like: GET, POST, PUT, DELETE. So we can properly show you how to unit test these services.

package com.memorynotfound.rs;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.List;

@Path("/notifications")
public class NotificationRestService {

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public List<Notification> fetchAll() {
        // fetch all notifications
        List<Notification> notifications = new ArrayList<Notification>();
        notifications.add(new Notification(1, "New user created"));
        notifications.add(new Notification(2, "New order created"));
        return notifications;
    }

    @GET
    @Path("{id: \\d+}")
    @Produces(MediaType.APPLICATION_JSON)
    public Notification fetchBy(@PathParam("id") int id) {
        // fetch notification by id
        return new Notification(id, "Rise and shine.");
    }

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public Notification create(Notification notification) {
        // create notification
        return notification;
    }

    @PUT
    @Consumes(MediaType.APPLICATION_JSON)
    public void update(Notification notification) {
        // update notification
    }

    @DELETE
    @Path("{id: \\d+}")
    @Produces(MediaType.APPLICATION_JSON)
    public void delete(@PathParam("id") int id) {
        // deleting notification
    }

}

Notification DTO (Data Transfer Object) used for automatic marshalling and data retrieval.

package com.memorynotfound.rs;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Notification {

    private Integer id;
    private String message;

    /**
     * Default no-args constructor needed for jaxb
     */
    public Notification() {
    }

    public Notification(Integer id, String message) {
        this.id = id;
        this.message = message;
    }

    public Integer getId() {
        return id;
    }

    public String getMessage() {
        return message;
    }
}

Jersey application Configuration. This configures jersey so we don’t need a web.xml file.

package com.memorynotfound.rs;

import java.util.HashMap;
import java.util.Map;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("/api")
public class ApplicationConfig extends Application {

    @Override
    public Map<String, Object> getProperties() {
        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put("jersey.config.server.provider.packages", "com.memorynotfound.rs");
        return properties;
    }
}

Test Jersey Rest Service with JUnit and Jersey

Testing with jersey Test Framework is relatively easy. You need to subclass org.glassfish.jersey.test.JerseyTest and configure the resource and/or providers that need to be deployed in order to test our services. We need to override the JerseyTest#configure() method to configure our application. In this example we return a ResourceConfig. The ResourceConfig is a sub-class of JAX-RS Application. It is a Jersey convenience class for configuring JAX-RS applications.

Finally we can write our JUnit tests. We obtain a WebTarget by calling the JerseyTest#target(path) method. It is on this target we can make a request, add parameters, headers, etc.. When the WebTarget is invoked we simply investigate the response namely the status code returned by the service.

package com.memorynotfound.rs.test;

import com.memorynotfound.rs.Notification;
import com.memorynotfound.rs.NotificationRestService;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.glassfish.jersey.test.TestProperties;
import org.junit.Test;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import static junit.framework.TestCase.assertNotNull;
import static org.junit.Assert.assertEquals;

public class NotificationRestServiceTest extends JerseyTest {

    @Override
    public Application configure() {
        enable(TestProperties.LOG_TRAFFIC);
        enable(TestProperties.DUMP_ENTITY);
        return new ResourceConfig(NotificationRestService.class);
    }

    @Test
    public void testFetchAll() {
        Response output = target("/notifications").request().get();
        assertEquals("should return status 200", 200, output.getStatus());
        assertNotNull("Should return list", output.getEntity());
    }

    @Test
    public void testFetchBy(){
        Response output = target("/notifications/1").request().get();
        assertEquals("Should return status 200", 200, output.getStatus());
        assertNotNull("Should return notification", output.getEntity());
    }

    @Test
    public void testFetchByFail_DoesNotHaveDigit(){
        Response output = target("/notifications/no-id-digit").request().get();
        assertEquals("Should return status 404", 404, output.getStatus());
    }

    @Test
    public void testCreate(){
        Notification notification = new Notification(null, "Invoice was deleted");
        Response output = target("/notifications")
                .request()
                .post(Entity.entity(notification, MediaType.APPLICATION_JSON));

        assertEquals("Should return status 200", 200, output.getStatus());
        assertNotNull("Should return notification", output.getEntity());
    }

    @Test
    public void testUpdate(){
        Notification notification = new Notification(1, "New user created at Antwerp");
        Response output = target("/notifications")
                .request()
                .put(Entity.entity(notification, MediaType.APPLICATION_JSON));
        assertEquals("Should return status 204", 204, output.getStatus());
    }

    @Test
    public void testDelete(){
        Response output = target("/notifications/1").request().delete();
        assertEquals("Should return status 204", 204, output.getStatus());
    }

}

References

Download

You may also like...

  • MD Aftab Alam

    great job !!