Reputation: 23226
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.
Upvotes: 1
Views: 2131
Reputation: 23226
My co-worker pointed out that the web.xml
is not actually used as part of the test stack. Instead I needed to initialize the filters programmatically; in our case our base test inherited from JerseyTest
and overwrote the configure
method:
@Override
protected AppDescriptor configure() {
return new WebAppDescriptor.Builder("com.yourproject.blah")
.initParam("com.sun.jersey.spi.container.ContainerRequestFilters",
"com.sun.jersey.api.container.filter.PostReplaceFilter")
.servletClass(SpringServlet.class)
.build();
}
Upvotes: 2