How to get instance of javax.ws.rs.core.UriInfo

前端 未结 3 1773
终归单人心
终归单人心 2020-12-17 18:21

Is there any implementation of javax.ws.rs.core.UriInfo which I can use to create an instance quickly for testing. This interface is long, I just need to test s

相关标签:
3条回答
  • 2020-12-17 18:44

    I was writing integration tests, so cannot use mock stuff

    I used some code for jersey tests

    http://www.programcreek.com/java-api-examples/index.php?source_dir=JerseyTest-master/jersey-tests/src/test/java/com/sun/jersey/impl/uri/UriPathHttpRequestTest.java

    WebApplicationImpl wai = new WebApplicationImpl();
    ContainerRequest r = new TestHttpRequestContext(wai,
                "GET", null,
                "/mycontextpath/rest/data", "/mycontextpath/");
    UriInfo uriInfo = new WebApplicationContext(wai, r, null);
    myresources.setUriInfo(uriInfo);
    

    and

    private static class TestHttpRequestContext extends ContainerRequest {
        public TestHttpRequestContext(
                WebApplication wa,
                String method,
                InputStream entity,
                String completeUri,
                String baseUri) {
            super(wa, method, URI.create(baseUri), URI.create(completeUri), new InBoundHeaders(), entity);
        }
    }
    

    If you get any errors about request scope beans see request scoped beans in spring testing

    0 讨论(0)
  • 2020-12-17 18:51

    You either mock it, or use something like http://arquillian.org/

    0 讨论(0)
  • 2020-12-17 18:54

    You simply inject it with the @Context annotation, as a field or method parameter.

    @Path("resource")
    public class Resource {
        @Context
        UriInfo uriInfo;
    
        public Response doSomthing(@Context UriInfo uriInfo) {
    
        }
    }
    

    Other than your resource classes, it can also be injected into other providers, like ContainerRequestContext, ContextResolver, MessageBodyReader etc.

    EDIT

    Actually I want to write a junit test for a function similar to your doSomthing() function.

    I didn't pick that up in your post. But a couple options I can think of for unit tests

    1. Simply create a stub, implementing only the methods you use.

    2. Use a Mocking framework like Mockito, and mock the UriInfo. Example

      @Path("test")
      public class TestResource { 
          public String doSomthing(@Context UriInfo uriInfo){
              return uriInfo.getAbsolutePath().toString();
          }
      }
      [...]
      @Test
      public void doTest() {
          UriInfo uriInfo = Mockito.mock(UriInfo.class);
          Mockito.when(uriInfo.getAbsolutePath())
              .thenReturn(URI.create("http://localhost:8080/test"));
          TestResource resource = new TestResource();
          String response = resource.doSomthing(uriInfo);
          Assert.assertEquals("http://localhost:8080/test", response);
      }
      

      You'll need to add this dependency

      <dependency>
          <groupId>org.mockito</groupId>
          <artifactId>mockito-all</artifactId>
          <version>1.9.0</version>
      </dependency>
      

    If you want to do an integration test, where the actual UriInfo is injected, you should look into Jersey Test Framework

    Here's a complete example with the Jersey Test Framework

    public class ResourceTest extends JerseyTest {
    
        @Path("test")
        public static class TestResource {
            @GET
            public Response doSomthing(@Context UriInfo uriInfo) {
                return Response.ok(uriInfo.getAbsolutePath().toString()).build();
            }
        }
    
        @Override
        public Application configure() {
            return new ResourceConfig(TestResource.class);
        }
    
        @Test
        public void test() {
            String response = target("test").request().get(String.class);
            Assert.assertTrue(response.contains("test"));
        }
    }
    

    Just add this dependency

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

    It uses an in-memory container, which is the most efficient for small tests. There are other containers with Servlet support if needed. Just see the link I posted above.

    0 讨论(0)
提交回复
热议问题