How to write Unit Test for this class using Jersey 2 test framework
java, jersey, jersey-2.0, rest, unit-testing
Solution
You can use the HK2 capabilities of Jersey 2, that helps with Dependency Injection. Doing it this way, you can create a `Factory` for `HttpServletRequest` and return the mock from your `RequestHelper`. For example
public class HttpServletRequestFactory implements Factory<HttpServlet> {
@Override
public HttpServletRequest provide() {
return RequestHelper.getMockServletRequest();
}
@Override
public void dispose(HttpSession t) {
}
}
Then in your `JerseyTest` subclass, just register an `AbstractBinder` with the `ResourceConfig`. For example
@Override
public Application configure() {
ResourceConfig config = new ResourceConfig(...);
config.register(new AbstractBinder(){
@Override
public void configure() {
bindFactory(HttpServletRequestFactory.class).to(HttpServletRequest.class);
}
});
}
Another option
...is to not mock the `HttpServletRequest` at all, and use the actual `HttpServletRequest`. To do that, we need to configure the `DeploymentContext` as we override the `getDeploymentContext()`, and return a `ServletDeploymentContext`. You can see an example here and here. The first has also has an example of using a `Factory`, while the second show an example of how to configure based on web.xml settings. If you chose the case for mocking the `HttpServletRequest`, then you wouldn't need to override the `getTestContainerFactory` and `configureDeployment` as seen in the examples. Simply using the `Application configure()` override is enough, as long as nothing else is dependent on servlet features.
The examples in the link use
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
<version>${jersey.version}</version>
</dependency>
Extra
Both the example I linked to are trying to take advantage of the Sevlet features. So I'll give a complete example of using a request mock.
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import org.glassfish.hk2.api.Factory;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Assert;
import org.junit.Test;
public class MockHttpSevletRequestTest extends JerseyTest {
@Path("http")
public static class HttpResource {
@GET
public Response getResponse(@Context HttpServletRequest request) {
return Response.ok(request.getMethod()).build();
}
}
@Override
public Application configure() {
ResourceConfig config = new ResourceConfig(HttpResource.class);
config.register(new AbstractBinder() {
@Override
public void configure() {
bindFactory(HttpServletRequestFactory.class)
.to(HttpServletRequest.class);
}
});
return config;
}
public static class HttpServletRequestFactory implements Factory<HttpServletRequest> {
@Override
public HttpServletRequest provide() {
return new MockHttpServletRequest();
}
@Override
public void dispose(HttpServletRequest t) {
}
}
@Test
public void test() {
String response = target("http").request().get(String.class);
System.out.println(response);
Assert.assertEquals("POST", response);
}
}
`MockHttpServletRequest` is simple a dummy implementation of `HttpServletRequest` where I only override one method `getMethod()` and always return `POST`. You can see from the result, that even though it's a `get` request, it still returns `POST`
public class MockHttpServletRequest implements HttpServletRequest {
@Override
public String getMethod() {
return "POST";
}
...
}
Problem
I am trying to write unit test for a Rest api call which is having a POST method for adding a video file to web based application using Jersey2. Here is the signature of the method of my class(`TemplateController.java`) for which I want to write unit test: ``` @POST @Path("/video/add") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Response addVideoData( @Context HttpServletRequest request, AttachmentDTO attachmentDTO) { ... } ``` Here is my test method of the test class (`TemplateControllerUnitTestCase.java`): ``` @Test public void videoAdd_requestObjectIsNull_ResponseStatusIsOK() throws Exception { // arrange Builder builder = target("/target/video/add").request(); // action final Response response = builder.post(Entity.entity(attachemntDTO, MediaType.APPLICATION_JSON)); // assertion ... } ``` I'm able to pass the `AttachmentDAO` object to the `TemplateController` class from test class but unable to pass the request object which is becoming null in the `method(addVideoData())` of the `TemplateController.java class`. I'm using `RequestHelper` class which is a helper class for `HttpServletRequest`, so I want to pass an object of this class to the `method(addVideoData())` using Jersey2 test framework.