[英]Mocking a Jersey REST Api running on Grizzly using Mockito
[英]How to write a test case for Jersey Rest resouce + Grizzly+mockito
我正在嘗試使用Spring的Grizzly和Mockito為Jersey編寫集成測試用例,但我無法模擬服務類。 如何模擬使用@AutoWired注入到我的Resource類中的服務類
@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();
}
這個測試用例正在通過,但是我嘲笑的服務類沒有嘲笑,當代碼擊中該行時,我得到了空指針異常
所以有幾個問題
@Before
方法。 JerseyTest
已經實現了@Before
方法 ,它在其中創建測試容器。 因此,您的模擬無法及時創建,服務將為空。 最好的辦法是在初始化Jersey應用程序的configureDeployment()
方法中創建服務。 將為每個測試用例創建一個新的容器,因此您將為每個測試使用新的模擬。
您只需將類傳遞給ResourceConfig
構造函數,這將使Jersey運行時創建資源類的實例。 因此,在創建資源類之后,請執行new ResourceConfig().register(resource)
而不是new ResourceConfig(MyResource.class)
new ResourceConfig().register(resource)
。
所以configureDeployment()
方法應該更像
@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;
}
另一個問題是您實際上沒有在請求中傳遞任何查詢參數。 因此,在您的資源方法中,參數將為null。 您的要求應該更像
target(...).queryParam(key1, value1).queryParam(key2, value2)
這是一個完整的測試
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);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.