作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 Grizzly 和 Mockito、Spring 为 Jersey 编写集成测试用例,但我无法模拟服务类。如何模拟使用 @AutoWired 注入(inject)到我的资源类中的服务类
@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
已经implements a @Before
method ,它在其中创建测试容器。因此,您的模拟不会及时创建,并且服务将为空。最好的办法是在 configureDeployment()
方法中创建服务,在该方法中初始化 Jersey 应用程序。将为每个测试用例创建一个新容器,因此每个测试都会有新的模拟。
您只需将该类传递给 ResourceConfig
构造函数,这将导致 Jersey 运行时创建资源类的实例。因此,创建资源类后,不要使用 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;
}
另一个问题是您实际上没有在请求中传递任何查询参数。因此,在您的资源方法中,参数将为空。您的请求应该看起来更像
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);
}
}
关于java - 如何为 Jersey Rest 资源 + Grizzly+mockito 编写测试用例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32264431/
我是一名优秀的程序员,十分优秀!