users@jersey.java.net

[Jersey] Test Framework: servletPath?

From: Stephen Friedrich <stephen_at_eekboom.de>
Date: Sat, 04 Dec 2010 00:14:20 +0100

It took me quite long to get the first test of My Guice/MyBatis/Jersey application running.

I finally got it working based on the guice example, but I wonder about "servletPath" setting.
My web apps registers the GuiceContainer to work on request with "api" prefix like this (so that it does not affect other, older parts of the app):
         Injector injector = Guice.createInjector(
                 new ServletModule() {
                     @Override
                     protected void configureServlets() {
                         serve("/api*").with(GuiceContainer.class, params);
                     }
                 }

After some experimentation I found that this test setup works:
public class MainTest extends JerseyTest {

     public MainTest() throws Exception {
         super(buildWebAppDescriptor());
     }

     private static WebAppDescriptor buildWebAppDescriptor() {
         WebAppDescriptor.Builder builder = new WebAppDescriptor.Builder();
         WebAppDescriptor webAppDescriptor = builder
                 .contextListenerClass(GuiceConfig.class)
                 .filterClass(GuiceFilter.class)
                 .contextPath("lernmich")
                 .servletPath("/api")
                 .build();
         return webAppDescriptor;
     }


But, now test requests must _ommit_ the "api" prefix:
         String cardSets = resource().path("card-sets").accept(MediaType.APPLICATION_JSON).get(String.class);
While in the "real" app, they must include it. Why is the servlet path treated like this?

Also it is _very strange_ that the following setup does not work, but does not give an error on the request, but only when I compare the results later:
     private static WebAppDescriptor buildWebAppDescriptor() {
         WebAppDescriptor.Builder builder = new WebAppDescriptor.Builder();
         WebAppDescriptor webAppDescriptor = builder
                 .contextListenerClass(GuiceConfig.class)
                 .filterClass(GuiceFilter.class)
                 .contextPath("lernmich")
                 .servletPath("/")
                 .build();
         return webAppDescriptor;

This looks like the request
         String cardSets = resource().path("card-sets").accept(MediaType.APPLICATION_JSON).get(String.class);
works, but gives the wrong result (however I checked with a debugger that the resource is in fact never called):
org.junit.ComparisonFailure:
Expected : ...
Actual :
        at org.junit.Assert.assertEquals(Assert.java:123)
        at org.junit.Assert.assertEquals(Assert.java:145)
        at de.eekboom.MainTest.testHelloWorld(MainTest.java:37)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)


BTW: The links to the jaxb-api and -impl jars in the user's guide "7.5. Running tests outside Maven" are broken - but it turned out that I don't need the jars at all.
However I need jackson-xc-1.6.2.jar on the classpath (which I don't need when running the app for real).