如何使用 Jersey 2 测试框架为此 class 编写单元测试
How to write Unit Test for this class using Jersey 2 test framework
我正在尝试为 Rest api 调用编写单元测试,该调用具有使用 Jersey2 将视频文件添加到基于 Web 的应用程序的 POST 方法。这是我要为其编写单元测试的 class(TemplateController.java
) 方法的签名:
@POST
@Path("/video/add")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response addVideoData(
@Context HttpServletRequest request,
AttachmentDTO attachmentDTO) {
...
}
下面是我的测试方法 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
...
}
我能够将 AttachmentDAO
对象从测试 class 传递到 TemplateController
class 但无法传递在method(addVideoData())
的 TemplateController.java class
.
我正在使用 RequestHelper
class,它是 HttpServletRequest
的助手 class,所以我想将此 class 的对象传递给method(addVideoData())
使用 Jersey2 测试框架。
您可以将 HK2 capabilities of Jersey 2, that helps with Dependency Injection. Doing it this way, you can create a Factory
用于 HttpServletRequest
和 return 来自您的 RequestHelper
的模拟。例如
public class HttpServletRequestFactory implements Factory<HttpServlet> {
@Override
public HttpServletRequest provide() {
return RequestHelper.getMockServletRequest();
}
@Override
public void dispose(HttpSession t) {
}
}
然后在您的 JerseyTest
子类中,只需用 ResourceConfig
注册一个 AbstractBinder
。例如
@Override
public Application configure() {
ResourceConfig config = new ResourceConfig(...);
config.register(new AbstractBinder(){
@Override
public void configure() {
bindFactory(HttpServletRequestFactory.class).to(HttpServletRequest.class);
}
});
}
另一种选择
...根本不模拟 HttpServletRequest
,而是使用实际的 HttpServletRequest
。为此,我们需要在覆盖 getDeploymentContext()
和 return 和 ServletDeploymentContext
时配置 DeploymentContext
。你可以看一个例子 and 。第一个还有一个使用 Factory
的示例,而第二个显示了如何根据 web.xml 设置进行配置的示例。如果您选择模拟 HttpServletRequest
的情况,那么您 将不会 需要覆盖 getTestContainerFactory
和 configureDeployment
,如示例中所示。只需使用 Application configure()
覆盖就足够了,只要没有其他依赖于 servlet 功能。
link中的例子使用
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
<version>${jersey.version}</version>
</dependency>
额外
我 link 编辑的两个示例都试图利用 Sevlet 功能。所以我将给出一个使用请求模拟的完整示例。
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
是 HttpServletRequest
的简单虚拟实现,其中我只重写一个方法 getMethod()
并且总是 return POST
。你可以从结果中看到,即使它是一个 get
请求,它仍然 returns POST
public class MockHttpServletRequest implements HttpServletRequest {
@Override
public String getMethod() {
return "POST";
}
...
}
我正在尝试为 Rest api 调用编写单元测试,该调用具有使用 Jersey2 将视频文件添加到基于 Web 的应用程序的 POST 方法。这是我要为其编写单元测试的 class(TemplateController.java
) 方法的签名:
@POST
@Path("/video/add")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response addVideoData(
@Context HttpServletRequest request,
AttachmentDTO attachmentDTO) {
...
}
下面是我的测试方法 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
...
}
我能够将 AttachmentDAO
对象从测试 class 传递到 TemplateController
class 但无法传递在method(addVideoData())
的 TemplateController.java class
.
我正在使用 RequestHelper
class,它是 HttpServletRequest
的助手 class,所以我想将此 class 的对象传递给method(addVideoData())
使用 Jersey2 测试框架。
您可以将 HK2 capabilities of Jersey 2, that helps with Dependency Injection. Doing it this way, you can create a Factory
用于 HttpServletRequest
和 return 来自您的 RequestHelper
的模拟。例如
public class HttpServletRequestFactory implements Factory<HttpServlet> {
@Override
public HttpServletRequest provide() {
return RequestHelper.getMockServletRequest();
}
@Override
public void dispose(HttpSession t) {
}
}
然后在您的 JerseyTest
子类中,只需用 ResourceConfig
注册一个 AbstractBinder
。例如
@Override
public Application configure() {
ResourceConfig config = new ResourceConfig(...);
config.register(new AbstractBinder(){
@Override
public void configure() {
bindFactory(HttpServletRequestFactory.class).to(HttpServletRequest.class);
}
});
}
另一种选择
...根本不模拟 HttpServletRequest
,而是使用实际的 HttpServletRequest
。为此,我们需要在覆盖 getDeploymentContext()
和 return 和 ServletDeploymentContext
时配置 DeploymentContext
。你可以看一个例子Factory
的示例,而第二个显示了如何根据 web.xml 设置进行配置的示例。如果您选择模拟 HttpServletRequest
的情况,那么您 将不会 需要覆盖 getTestContainerFactory
和 configureDeployment
,如示例中所示。只需使用 Application configure()
覆盖就足够了,只要没有其他依赖于 servlet 功能。
link中的例子使用
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
<version>${jersey.version}</version>
</dependency>
额外
我 link 编辑的两个示例都试图利用 Sevlet 功能。所以我将给出一个使用请求模拟的完整示例。
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
是 HttpServletRequest
的简单虚拟实现,其中我只重写一个方法 getMethod()
并且总是 return POST
。你可以从结果中看到,即使它是一个 get
请求,它仍然 returns POST
public class MockHttpServletRequest implements HttpServletRequest {
@Override
public String getMethod() {
return "POST";
}
...
}