Jersey client API vs Jersey test framework

user1247412 picture user1247412 · Nov 27, 2014 · Viewed 13.9k times · Source

I am new to web services and would like to know what is the difference between Jersey client API and jersey test framework?

I would like to test my jersey REST web-services end points. Which is the the right one to use?

Answer

Paul Samsotha picture Paul Samsotha · Nov 27, 2014

There are many HTTP client APIs out there (for example Apache HttpClient). You will need one to do client side testing. We will need to somehow access our services through HTTP, so one of these APIs will be needed for unit testing. Since you're already using Jersey, the Jersey Client API is a good choice. An example might look something like

final String url = "http://stackoverflow.com/questions/27160440/" +
                                   "jersey-client-api-vs-jersey-test-framework";
Client client = ClientBuilder.newClient();
WebTarget target = client.target(url);
Response response = target.request().accept(MediaType..get();
String html  = response.readEntity(String.class);
System.out.println(html);
response.close();

As you can see the client API does not have to be calling our services. It is just interface to HTTP calls, with "Rest" features. If we wanted to run our own services, we would first need to deploy them to a container, whether a full blown server/container, or some embedded variant. Without a framework, a full test might look something like

<dependencies>
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-grizzly2-http</artifactId>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.9</version>
        <scope>test</scope>
    </dependency>
</dependencies>

public class SimpleTest {

    static final String BASE_URI = "http://localhost:8080/myapp/";
    static HttpServer server;
    static Client client;

    private static HttpServer startServer() {
        final ResourceConfig resourceConfig = new ResourceConfig()
                .packages("where.my.resources.are")
                .register(HelloResource.class);
                // normally the resource class would not be in the unit test class
                // and would be in the `where.my.resources.are` package pr sub package
        return GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), resourceConfig);
    }

    @Path("hello")
    public static class HelloResource {
        @GET
        public String getHello() {
            return "Hello World!";
        }
    }

    @BeforeClass
    public static void setUpClass() {
        server = startServer();
        client = ClientBuilder.newClient();
    }

    @AfterClass
    public static void tearDownClass() {
        server.shutdown();
    }

     @Test
    public void test() {
        WebTarget target = client.target(BASE_URI);
        Response response = target.path("hello").request().get();
        String hello = response.readEntity(String.class);
        assertEquals("Hello World!", hello);
        response.close();
    }
}

The Jersey Test Framework allows us to do semi-integration/integration testing more easily, with options for more complex container deployments. The services can be launched into a lightweight embedded container (also different types) which will auto start and stop on running the unit tests. The framework is actually dependent on the Jersey Client API, so if you are using the framework, then you can use the Client API in your test cases. An example

<dependencies>
    <dependency>
        <groupId>org.glassfish.jersey.test-framework.providers</groupId>
        <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
        <version>2.13</version>
    </dependency>
</dependencies>

public class SimpleTest extends JerseyTest {

    @Path("hello")
    public static class HelloResource {
        @GET
        public String getHello() {
            return "Hello World!";
        }
    }

    @Override
    protected Application configure() {
        return new ResourceConfig(HelloResource.class);
    }

    @Test
    public void test() {
        Response response = target("hello").request().get();
        String hello = response.readEntity(String.class);
        assertEquals("Hello World!", hello);
        response.close();
    }
}

You can see similarities, the @Test. That's because, we are making use of the client API. We don't need to explicitly configure the Client, as the framework does this for us.

So the choice really comes down to whether or not you want to use the Test framework. Either way you should know how to use the Jersey Client API, as you will be using it either way (that is unless you decide to just go with another HTTTP client API like HttpClient)


Read More