Rest - Jersey Test FrameworkThis chapter will present how to write tests for your resources using Jersey Test Framework and how to run them in various containers. Additionally it will explain how to create new module for not yet supported container. Jersey currently provides following modules:
There are some significant breaking changes in Jersey 1.2. In prior Jersey versions users were able to select container factory just by specifying it in some property. That was convenient from user perspective but not good from build perspective. Former test framework artifact was dependent on all containers which is useless in most cases (usually you test only with one container). Solution to this is modularization - make module for each test container. It has one drawback: users will have to have other dependency in their applications, for example if you want to test on embedded grizzly container, you will declare (only) dependency on jersey test framework grizzly module. You can declare multiple test containers this way and select one by defining property jersey.test.containerFactory. Another change (non-breaking) is renaming Jersey parameters which control container factory, used port and host name for external container. Old properties are still working but users are encouraged to use new ones. Table 7.1. Property name changes
When you want test your resources in maven-based project, you need to add dependency on one of the Jersey Test Framework modules. You can take a look at helloworld sample pom file. There is declared dependency on:
<dependency>
<groupId>com.sun.jersey.jersey-test-framework</groupId> <artifactId>jersey-test-framework-grizzly2</artifactId> <version>${project.version}</version> <scope>test</scope> </dependency> which means that Grizzly Web container (version 2.x) will be used for testing. You can specify more than one module in dependencies and choose which module will be used by jersey.test.containerFactory property. Every module should contain at least one container factory. jersey-test-framework-grizzly
com.sun.jersey.test.framework.spi.container.grizzly.web.GrizzlyWebTestContainerFactory com.sun.jersey.test.framework.spi.container.grizzly.GrizzlyTestContainerFactory
jersey-test-framework-grizzly2
com.sun.jersey.test.framework.spi.container.grizzly2.web.GrizzlyWebTestContainerFactory com.sun.jersey.test.framework.spi.container.grizzly2.GrizzlyTestContainerFactory
jersey-test-framework-http
com.sun.jersey.test.framework.spi.container.http.HTTPContainerFactory
jersey-test-framework-inmemory
com.sun.jersey.test.framework.spi.container.inmemory.InMemoryTestContainerFactory
jersey-test-framework-embedded-glassfish
com.sun.jersey.test.framework.spi.container.embedded.glassfish.EmbeddedGlassFishTestContainerFactory
jersey-test-framework-external
com.sun.jersey.test.framework.spi.container.external.ExternalTestContainerFactory
Basically you can just add dependency on single module and its container factory would be used. Problem is when you specify module which has more than one container factory or multiple modules. If this happen, test framework will choose factory using following rules:
if("jersey.test.containerFactory" not specified)
look for factories if(factories.count == 1) use found factory else if(com.sun.jersey.test.framework.spi.container.grizzly2.web.GrizzlyWebTestContainerFactory is present) use it // current default jersey test container factory else use first found and log warning else use factory class specified in "jersey.test.containerFactory" That means if your project depends on multiple test framework modules and you want to control which will be used, you have to declare which one in property called "jersey.test.containerFactory", for example like this: mvn clean install -Djersey.test.containerFactory=com.sun.jersey.test.framework.spi.container.inmemory.InMemoryTestContainerFactory 7.3. Creating tests Jersey Test Framework uses JUnit version 4.X, so if you can write standard unit tests, you can easily create Jersey Test. You need to declare test as a descendant of JerseyTest class.
public class MainTest extends JerseyTest {
public MainTest()throws Exception { super("com.sun.jersey.samples.helloworld.resources"); } @Test public void testHelloWorld() { WebResource webResource = resource(); String responseMsg = webResource.path("helloworld").get(String.class); assertEquals("Hello World", responseMsg); } } Note super call in constructor - it passes list of package names to scan (it really is a list, JerseyTest constructor has variable argument count). Another useful method is resource() which returns WebResource instance with URI set to base URI of your application. You can get preconfigured Jersey Client instance similarly by calling client() method. 7.4. Creating own module Creating your own module is pretty straightforward, you just have to implement com.sun.jersey.test.framework.spi.container.TestContainerFactory and com.sun.jersey.test.framework.spi.container.TestContainer. TestContainer factory is there basically for returning TestContainer instance and TestContainer has self-explanatory methods: start(), stop(), getClient() and getBaseURI(). I recommend taking look at source code and read javadoc of these two classes, all you need is there. You should be avare of another thing when implementing own jersey test framework module. If you want it to be usable by running just mvn clean install (when only your module is specified), you need to add META-INF/services/com.sun.jersey.test.framework.spi.container.TestContainerFactory file into your jar and put there your factory class (fully classified) name. 7.5. Running tests outside Maven Since Jersey is Maven based project, executing tests without Maven can be painful. You have to have everything needed present on classpath and by everything is meant following list:
As was already written above, Jersey test is descendant of standard unit test so it can be run same way. You can execute it by executing org.junit.runner.JUnitCore and passing your test class name as parameter, from ant (junit-task) or whatever you are used to. |