Mock Service inside resource using jersey test framwork

Shiran Maor picture Shiran Maor · Jan 19, 2016 · Viewed 9.7k times · Source

I have a resource for rest API which uses a service. This service has a constructor with parameters. I want to test this resource and to mock this service. This Question: How to pass parameters to REST resource using Jersey 2.5

wasn't helpful because they used @Inject and I cannot use it. Any suggestions?

The second question is how do I pass parameter to test this resouce: My code is:

@Path("/2/{subversion: [0-3]}/users")
public class UserResource {
    Logger log = Logger.getLogger(UserResource.class);
    private MyService service;
    public void setService(Service ser) {
        this.service = ser;
    }

@Context HttpServletRequest currentRequest;

@GET
@Produces("application/json")
public Response getUsers(@Context HttpHeaders httpHeaders, @Context UriInfo
uriInfo) {
// my function
}
}

How can I pass "httpHeaders" and "UriInfo". My test looks like this:

Response response = target("/2/0/users/").request().get();
Users users = response.readEntity(Users.class);
assertNotNull(users);

Answer

Paul Samsotha picture Paul Samsotha · Jan 20, 2016

For the service, it's good practice to either inject through the constructor or setter. This makes it easy to mock and pass in during unit testing. As for the mocking, you should use a framework like Mockito. Then you can do stuff like

MyService service = Mockito.mock(MyService.class);
when(service.getObject()).thenReturn(new Object());

HttpHeaders headers = Mockito.mock(HttpHeaders.class);
when(headers.getHeaderString("X-Header")).thenReturn("blah");

UriInfo uriInfo = Mockito.mock(UriInfo.class);
when(uriInfo.getRequestUri()).thenReturn(URI.create("http://localhost"));

Then you can just pass all these mocks to your resource class when UNIT testing.

For INTEGRATION testing you won't need to mock the headers or uriinfo. The actual ones will get passed in. But you can still mock the service if you want. Here's an example

public class MockServiceTest extends JerseyTest  {

    public static interface Service {
        String getMessage(String name);
    }

    @Path("message")
    public static class MessageResource {

        private final Service service;

        public MessageResource(Service service) {
            this.service = service;
        }

        @GET
        public String get(@QueryParam("name") String name,
                          @Context HttpHeaders headers,
                          @Context UriInfo uriInfo) {
            String nameQuery = uriInfo.getQueryParameters().getFirst("name");
            String header = headers.getHeaderString("X-Header");
            assertNotNull(nameQuery);
            assertNotNull(header);
            return service.getMessage(name);
        }
    }

    private Service service;

    @Override
    public ResourceConfig configure() {
        service = Mockito.mock(Service.class);
        return new ResourceConfig().register(new MessageResource(service));
    }

    @Test
    public void testIt() {
        Mockito.when(service.getMessage("peeskillet")).thenReturn("Hello peeskillet");

        Response response = target("message").queryParam("name", "peeskillet").request()
                .header("X-Header", "blah")
                .get();
        assertEquals(200, response.getStatus());
        assertEquals("Hello peeskillet", response.readEntity(String.class));
    }
}