如何使用Jersey 2测试框架为此类编写单元测试 [英] How to write Unit Test for this class using Jersey 2 test framework

查看:88
本文介绍了如何使用Jersey 2测试框架为此类编写单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为Rest api调用编写单元测试,该调用具有POST方法,该方法用于使用Jersey2将视频文件添加到基于Web的应用程序中.这是我要为其编写单元测试的类(TemplateController.java)的方法的签名:

I am trying to write unit test for a Rest api call which is having a POST method for adding a video file to web based application using Jersey2. Here is the signature of the method of my class(TemplateController.java) for which I want to write unit test:

@POST
@Path("/video/add")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response addVideoData(
    @Context HttpServletRequest request, 
    AttachmentDTO attachmentDTO) {
        ...
}

这是我的测试类(TemplateControllerUnitTestCase.java)的测试方法:

Here is my test method of the test 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对象从测试类传递到TemplateController类,但是无法传递在TemplateController.java classmethod(addVideoData())中变为空的请求对象.

I'm able to pass the AttachmentDAO object to the TemplateController class from test class but unable to pass the request object which is becoming null in the method(addVideoData()) of the TemplateController.java class.

我正在使用RequestHelper类,它是HttpServletRequest的辅助类,因此我想使用Jersey2测试框架将该类的对象传递给method(addVideoData()).

I'm using RequestHelper class which is a helper class for HttpServletRequest, so I want to pass an object of this class to the method(addVideoData()) using Jersey2 test framework.

推荐答案

您可以使用泽西岛2的HK2 功能,可帮助依赖注入.这样,您可以创建 Factory for HttpServletRequest,然后从您的RequestHelper返回模拟.例如

You can use the HK2 capabilities of Jersey 2, that helps with Dependency Injection. Doing it this way, you can create a Factory for HttpServletRequest and return the mock from your RequestHelper. For example

public class HttpServletRequestFactory implements Factory<HttpServlet> {

    @Override
    public HttpServletRequest provide() {
       return RequestHelper.getMockServletRequest();
    }

    @Override
    public void dispose(HttpSession t) {
    }
}

然后在您的JerseyTest子类中,只需向ResourceConfig注册一个AbstractBinder.例如

Then in your JerseyTest subclass, just register an AbstractBinder with the ResourceConfig. For example

@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()的同时配置DeploymentContext,并返回ServletDeploymentContext.您可以在此处这里.第一个例子有使用Factory的示例,第二个例子有基于web.xml设置的配置示例.如果选择模拟HttpServletRequest的情况,那么不需要可以覆盖示例中所见的getTestContainerFactoryconfigureDeployment.只要Application configure()覆盖就足够了,只要其他都没有依赖servlet功能即可.

Another option

...is to not mock the HttpServletRequest at all, and use the actual HttpServletRequest. To do that, we need to configure the DeploymentContext as we override the getDeploymentContext(), and return a ServletDeploymentContext. You can see an example here and here. The first has also has an example of using a Factory, while the second show an example of how to configure based on web.xml settings. If you chose the case for mocking the HttpServletRequest, then you wouldn't need to override the getTestContainerFactory and configureDeployment as seen in the examples. Simply using the Application configure() override is enough, as long as nothing else is dependent on servlet features.

链接中的示例使用

<dependency>
    <groupId>org.glassfish.jersey.test-framework.providers</groupId>
    <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
    <version>${jersey.version}</version>
</dependency>

额外

我链接到的两个示例都试图利用Sevlet功能.因此,我将给出一个使用请求模拟的完整示例.

Extra

Both the example I linked to are trying to take advantage of the Sevlet features. So I'll give a complete example of using a request mock.

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);
    }
}

MockHttpServletRequestHttpServletRequest的简单虚拟实现,其中我仅重写一个方法getMethod()并始终返回POST.您可以从结果中看到,即使这是一个get请求,它仍然会返回POST

MockHttpServletRequest is simple a dummy implementation of HttpServletRequest where I only override one method getMethod() and always return POST. You can see from the result, that even though it's a get request, it still returns POST

public class MockHttpServletRequest implements HttpServletRequest {

    @Override
    public String getMethod() {
        return "POST";
    }
    ...
}

这篇关于如何使用Jersey 2测试框架为此类编写单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆