Friday, January 15, 2016

Dropwizard MessageBodyWriter not found when Unit-Testing Jersey Resources

Resource-class:
@POST
@Produces(MediaType.TEXT_HTML)
@Path("login")
public Response login(..) {
    ..
    View view = new ParamView("test/views/Login.mustache")
    return Response.ok().entity(view).build()
}

Unit-Test:
class LoginResourceTest {
    @ClassRule
    public static final ResourceTestRule resources = ResourceTestRule.builder()
        //.addProvider(new ViewMessageBodyWriter(new MetricRegistry()))
        .addResource(LoginResource.class)
        .build();

    @Test
    public void login() {
        def params = new MultivaluedHashMap([email: 'user@company.com', password: 'test'])
        def res = resources.getJerseyTest()
                .target("/login")
                .request(MediaType.TEXT_HTML_TYPE)
                .post(Entity.entity(params, MediaType.APPLICATION_FORM_URLENCODED_TYPE))
        assertThat(res.getStatus()).isEqualTo(200)
    }

---

Actual code runs ok when used with browser, when Dropwizard application server is running but when executed via JUnit test it causes following error:

ERROR [2016-01-15 18:48:26,244] org.glassfish.jersey.message.internal.WriterInterceptorExecutor: MessageBodyWriter not found for media type=text/html, type=class test.resources.MyView, genericType=class test.resources.MyView.

Reason why this happens is that Dropwizard's unit-testing setup is not identical to running server, and it seems that DW doesn't register the ViewMessageBodyWriter that does the rendering of Mustache and Freemarker templates to text/html format.

In DW server this is done by:
    bootstrap.addBundle(new ViewBundle());

during Application.initialize() but there are no Bootstraps or Bundles in unit-testing setup. 

So just un-comment that line from the ResourceTestRule and it starts working.

I assume DW will fix this sooner or later.

No comments:

Post a Comment