How to write Unit Test for this class using Jersey 2 test framework

前端 未结 1 1654
傲寒
傲寒 2021-01-01 07:15

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

相关标签:
1条回答
  • 2021-01-01 07:42

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

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

    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.

    The examples in the link use

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

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

    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";
        }
        ...
    }
    
    0 讨论(0)
提交回复
热议问题