Reputation: 277
I am trying to write integration test case for Jersey Using Grizzly and Mockito, Spring, I am not able to mock the service Class. how can I mock the service class which is injected in my Resource class with @AutoWired
@AutoWired
MyFirstService myFirstServiceImpl;
@AutoWired
MySecondService mySecondServiceImpl;
@GET
@Path("/abc")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response getDetails(@QueryParam("xyz") String xyz,
@QueryParam("pqr") String pqr) {
Gson gson = new Gson();
Map<String, Object> someMap= new HashMap<String, Object>();
try {
map.put("a", myFirstServiceImpl.getSomeDetails(xyz);
map.put("b", mySecondService.getSomeMoreDetails(pqr);
} catch (Exception e) {
e.printStackTrace();
}
return Response.status(200).entity(gson.toJson(someMap)).build();
}
Test Class:
@Mock
private static MySecondService mySecondServiceImpl;;
@Mock
private static MyFirstService myFirstServiceImpl;
@Before
public void initMocks() {
resource = new MyResource();
MockitoAnnotations.initMocks(this);
resource.setMyFirstService (firstService);
resource.setSecondService(secondService);
}
@Override
protected TestContainerFactory getTestContainerFactory() {
return new GrizzlyWebTestContainerFactory();
}
private DeploymentContext getRestResourcesWithFilter() {
System.setProperty("jersey.config.test.container.port", "8104");
ServletDeploymentContext context =
ServletDeploymentContext
.forServlet(
new ServletContainer(new ResourceConfig(MyResource.class).property(
ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR, "true")))
.addListener(ContextLoaderListener.class).addListener(RequestContextListener.class)
.initParam("contextConfigLocation", "classpath:applicationContext.xml")
.build();
return context;
@Test
public void test() throws Exception {
SomeOBject object= new SomeObject();
Object2 obj= new Object2();
when(myFirstServiceImpl.getSomeDetails(any(String.class))).thenReturn(object);
when(mySecondService.getSomeMoreDetails(pqr)).thenReturn(obj);
Response response = target("v1/abc").request().get();
}
This Test case is passing but the service class which I mocked are not mocking I am getting null pointer exception when ever code hits that line
Upvotes: 1
Views: 1995
Reputation: 208944
So there are a couple problems
The @Before
method. JerseyTest
already implements a @Before
method, where it creates the test container. So your mocks won't be created in time and the services will be null. Best thing to do is to just create the services in the configureDeployment()
method, where you are initializing the Jersey application. A new container will be created for each test case, so you will have new mocks for each test.
You are simple passing the class to the ResourceConfig
constructor, which will cause the Jersey runtime to create the instance of the resource class. So after you create the resource class, instead of new ResourceConfig(MyResource.class)
, do new ResourceConfig().register(resource)
.
So the configureDeployment()
method should look more like
@Override
public DeploymentContext configureDeployment() {
resource = new MyResource();
MockitoAnnotations.initMocks(this);
resource.setMyFirstService(firstService);
resource.setSecondService(secondService);
ServletDeploymentContext context
= ServletDeploymentContext.forServlet(
new ServletContainer(new ResourceConfig().register(resource).property(
ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR, "true")))
.build();
return context;
}
Another problem is that you are not actually passing any query parameters in the request. So in your resource method, the parameters will be null. Your request should look more like
target(...).queryParam(key1, value1).queryParam(key2, value2)
Here is a complete test
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import junit.framework.Assert;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.ServerProperties;
import org.glassfish.jersey.servlet.ServletContainer;
import org.glassfish.jersey.test.DeploymentContext;
import org.glassfish.jersey.test.JerseyTest;
import org.glassfish.jersey.test.ServletDeploymentContext;
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
import org.glassfish.jersey.test.spi.TestContainerFactory;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
public class MockitoTest extends JerseyTest {
public static interface Service {
String getMessage(String name);
}
@Mock
private Service service;
@Path("mock")
public static class MyResource {
private Service service;
public void setService(Service service) {
this.service = service;
}
@GET
public String get(@QueryParam("name") String name) {
return service.getMessage(name);
}
}
@Override
public DeploymentContext configureDeployment() {
MyResource resource = new MyResource();
MockitoAnnotations.initMocks(this);
resource.setService(service);
ServletDeploymentContext context
= ServletDeploymentContext.forServlet(
new ServletContainer(new ResourceConfig().register(resource).property(
ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR, "true")))
.build();
return context;
}
@Override
protected TestContainerFactory getTestContainerFactory() {
return new GrizzlyWebTestContainerFactory();
}
@Test
public void doTest() {
Mockito.when(service.getMessage(Mockito.anyString())).thenAnswer(new Answer<String>(){
@Override
public String answer(InvocationOnMock invocation) throws Throwable {
return "Hello " + (String)invocation.getArguments()[0];
}
});
Response response = target("mock").queryParam("name", "peeskillet").request().get();
Assert.assertEquals(200, response.getStatus());
String message = response.readEntity(String.class);
Assert.assertEquals("Hello peeskillet", message);
System.out.println(message);
}
}
Upvotes: 2