Table of Contents
Jersey Test Framework originated as an internal tool used for verifying the correct implementation of server-side components. Testing RESTful applications became a more pressing issue with "modern" approaches like test-driven development and users started to look for a tool that could help with designing and running the tests as fast as possible but with many options related to test execution environment.
Current implementation of Jersey Test Framework supports the following set of features:
pre-configured client to access deployed application
support for multiple containers - grizzly, in-memory, jdk, simple, jetty
able to run against any external container
automated configurable traffic logging
Jersey Test Framework is based on JUnit and works almost out-of-the box. It is easy to integrate it within your Maven-based project. While it is usable on all environments where you can run JUnit, we support primarily the Maven-based setups.
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() { final String hello = target("hello").request().get(String.class); assertEquals("Hello World!", hello); } }
If you want to develop a test using Jersey Test Framework, you need to subclass JerseyTest and
configure the set of resources and/or providers that will be deployed as part of the test application. This short
code snippet shows basic resource class HelloResource
used in tests defined as part of the
SimpleTest
class. The overridden configure
method returns
a ResourceConfig of the test application,that contains only the HelloResource
resource class. ResourceConfig
is a sub-class of JAX-RS Application. It is a Jersey
convenience class for configuring JAX-RS applications. ResourceConfig
also implements JAX-RS
Configurable interface to make the application configuration more flexible.
JerseyTest supports deploying applications on various containers, all (except the external container
wrapper) need to have some "glue" code to be supported. Currently Jersey Test Framework provides support for
Grizzly, In-Memory, JDK (com.sun.net.httpserver.HttpServer
), Simple HTTP container
(org.simpleframework.http
) and Jetty HTTP container (org.eclipse.jetty
).
A test container is selected based on various inputs.
JerseyTest#getTestContainerFactory()
is always executed, so if you override it and provide your own version of
TestContainerFactory, nothing else will be considered.
Setting a system variable
TestProperties#CONTAINER_FACTORY
has similar effect. This way you may defer the decision on which containers you want to run your tests
from the compile time to the test execution time.
Default implementation of TestContainerFactory
looks for container factories on classpath.
If more than one instance is found and there is a Grizzly test container factory among them, it will be used; if not,
a warning will be logged and the first found factory will be instantiated.
Following is a brief description of all containers supported in Jersey Test Framework.
Grizzly container can run as a light-weight, plain HTTP container. Almost all Jersey tests are using Grizzly by default.
<dependency> <groupId>org.glassfish.jersey.test-framework.providers</groupId> <artifactId>jersey-test-framework-provider-grizzly2</artifactId> <version>2.6</version> </dependency>
In-Memory container is not a real container. It starts Jersey application and directly calls internal APIs to handle request created by client provided by test framework. There is no network communication involved. This containers does not support servlet and other container dependent features, but it is a perfect choice for simple unit tests.
<dependency> <groupId>org.glassfish.jersey.test-framework.providers</groupId> <artifactId>jersey-test-framework-provider-inmemory</artifactId> <version>2.6</version> </dependency>
HttpServer
from Oracle JDK is another supported test container.
<dependency> <groupId>org.glassfish.jersey.test-framework.providers</groupId> <artifactId>jersey-test-framework-provider-jdk-http</artifactId> <version>2.6</version> </dependency>
Simple container (org.simpleframework.http
) is another light-weight HTTP container
that integrates with Jersey and is supported by Jersey Test Framework.
<dependency> <groupId>org.glassfish.jersey.test-framework.providers</groupId> <artifactId>jersey-test-framework-provider-simple</artifactId> <version>2.6</version> </dependency>
Jetty container (org.eclipse.jetty
) is another high-performance, light-weight HTTP server
that integrates with Jersey and is supported by Jersey Test Framework.
<dependency> <groupId>org.glassfish.jersey.test-framework.providers</groupId> <artifactId>jersey-test-framework-provider-jetty</artifactId> <version>2.6</version> </dependency>
JerseyTest
provide
enable(...),
forceEnable(...)
and disable(...)
methods, that give you control over configuring values of the properties defined and described in the
TestProperties
class. A typical code that overrides the default property values is listed
bellow:
public class SimpleTest extends JerseyTest { // ... @Override protected Application configure() { enable(TestProperties.LOG_TRAFFIC); enable(TestProperties.DUMP_ENTITY); // ... } }
The code in the example above enables test traffic logging (inbound and outbound headers) as well as dumping the HTTP message entity as part of the traffic logging.
Complicated test scenarios may require fully started containers with complex setup configuration, that is not easily doable with current Jersey container support. To address these use cases, Jersey Test Framework providers general fallback mechanism - an External Test Container Factory. Support of this external container "wrapper" is provided as the following module:
<dependency> <groupId>org.glassfish.jersey.test-framework.providers</groupId> <artifactId>jersey-test-framework-provider-external</artifactId> <version>2.6</version> </dependency>
As indicated, the "container" exposed by this module is just a wrapper or stub, that redirects all request to a configured host and port. Writing tests for this container is same as for any other but you have to provide the information about host and port during the test execution:
mvn test -Djersey.test.host=myhost.org -Djersey.config.test.container.port=8080
Tests might require some advanced client configuration. This is possible by overriding configureClient(ClientConfig clientConfig) method. Typical use case for this is registering more providers, such as MessageBodyReader<T>s or MessageBodyWriter<T>s, or enabling additional features.
Sometimes you might need to check a logged message as part of your test assertions. For this purpose Jersey Test Framework provides convenient access to the logged records via JerseyTest#getLastLoggedRecord() and JerseyTest#getLoggedRecords() methods. Note that this feature is not enabled by default, see TestProperties#RECORD_LOG_LEVEL for more information.