I’m using Jersey 1.11 and trying to model both POST and DELETE methods in my RESTful resource.
The problem I am encountering is in my unit tests. I cannot use the delete method of WebResource and still expect a ContentResponse instance (there are workarounds but since I will at some point use a Rails front end I’d rather sort this out now). So I’m trying to use POST with the PostReplaceFilter and have variously tried submitting form and query _method parameters (set to DELETE) as well as the X-HTTP-Method-Override header.
I am configuring the PostReplaceFilter in web.xml as such:
<servlet-name>SomeName</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
<param-value>com.sun.jersey.api.container.filter.PostReplaceFilter</param-value>
</init-param>
My REST resource looks like this:
@Controller
@Scope("prototype")
@Path("{apiVersion}/push/")
public class Push extends BaseRequest {
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces(MediaType.APPLICATION_JSON)
@Path("registration")
public Response create(@FormParam(REGISTRATION_ID_FIELD) String registrationId) throws Exception {
/* omitted; this method ends in a 200 OK */
}
@DELETE
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("registration")
public Response destroy(@FormParam(REGISTRATION_ID_FIELD) String registrationId) throws Exception {
/* omitted; this method ends in a 204 NO CONTENT */
}
My unit test always invokes the first create method as if the PostReplaceFilter is having no effect:
private WebResource.Builder prepare(String path, String method) {
return resource().path(path)
.queryParam("_method", method)
.cookie(new Cookie(Report.DEVICE_COOKIE_NAME, TEST_DEVICE_ID))
.cookie(new Cookie(Report.TOKEN_COOKIE_NAME, TEST_TOKEN));
}
@Test
public void destroyShouldEliminateAnyPushRegistrationAndTokenForADevice() throws Exception {
// mocks are setup here
MultivaluedMap<String, String> formData = createFormData(registrationId);
ClientResponse response = prepare("/1.0/push/registration", "DELETE")
.header("X-HTTP-Method-Override", "DELETE")
.post(ClientResponse.class, formData);
assertThat(response.getStatus(), is(204));
// mocks are verified here
}
I know the first method is being invoked because create returns a 200 while the destroy method returns 204 and the assertThat line is failing due to a 200 status (additionally my expected methods on my mocks are not being invoked).
My unit test inherits from JerseyTest and uses the Grizzly2 Web Container.
My co-worker pointed out that the
web.xmlis not actually used as part of the test stack. Instead I needed to initialize the filters programmatically; in our case our base test inherited fromJerseyTestand overwrote theconfiguremethod: