2016-01-19 4 views
5

Ich habe eine Ressource für Rest-API, die einen Dienst verwendet. Dieser Dienst verfügt über einen Konstruktor mit Parametern. Ich möchte diese Ressource testen und diesen Dienst verspotten. Diese Question: How to pass parameters to REST resource using Jersey 2.5Mock Service innerhalb Ressource mit Jersey Test framwork

war nicht hilfreich, weil sie @Inject verwendet und ich kann es nicht verwenden. Irgendwelche Vorschläge?

Die zweite Frage ist, wie kann ich Parameter übergeben diese resouce testen: Mein Code ist:

@Path("/2/{subversion: [0-3]}/users") 
public class UserResource { 
    Logger log = Logger.getLogger(UserResource.class); 
    private MyService service; 
    public void setService(Service ser) { 
     this.service = ser; 
    } 

@Context HttpServletRequest currentRequest;

Wie kann ich "httpHeaders" und "UriInfo" übergeben. Mein Test wie folgt aussieht:

Response response = target("/2/0/users/").request().get(); 
Users users = response.readEntity(Users.class); 
assertNotNull(users); 

Antwort

7

Für den Service, ist es empfehlenswert, entweder durch den Hersteller oder Setter zu injizieren. Dies macht es einfach, während des Komponententests zuzuspielen und weiterzugeben. Was das Mocking betrifft, sollten Sie ein Framework wie Mockito verwenden. Dann können Sie Sachen wie

MyService service = Mockito.mock(MyService.class); 
when(service.getObject()).thenReturn(new Object()); 

HttpHeaders headers = Mockito.mock(HttpHeaders.class); 
when(headers.getHeaderString("X-Header")).thenReturn("blah"); 

UriInfo uriInfo = Mockito.mock(UriInfo.class); 
when(uriInfo.getRequestUri()).thenReturn(URI.create("http://localhost")); 

tun Dann können Sie einfach alle diese Mocks auf Ihre Ressource-Klasse übergeben, wenn UNIT Tests.

Für INTEGRATION Testen müssen Sie nicht die Header oder Uriinfo verspotten. Die eigentlichen werden übergangen werden. Aber Sie können immer noch den Dienst verspotten, wenn Sie wollen. Hier ist ein Beispiel

public class MockServiceTest extends JerseyTest { 

    public static interface Service { 
     String getMessage(String name); 
    } 

    @Path("message") 
    public static class MessageResource { 

     private final Service service; 

     public MessageResource(Service service) { 
      this.service = service; 
     } 

     @GET 
     public String get(@QueryParam("name") String name, 
          @Context HttpHeaders headers, 
          @Context UriInfo uriInfo) { 
      String nameQuery = uriInfo.getQueryParameters().getFirst("name"); 
      String header = headers.getHeaderString("X-Header"); 
      assertNotNull(nameQuery); 
      assertNotNull(header); 
      return service.getMessage(name); 
     } 
    } 

    private Service service; 

    @Override 
    public ResourceConfig configure() { 
     service = Mockito.mock(Service.class); 
     return new ResourceConfig().register(new MessageResource(service)); 
    } 

    @Test 
    public void testIt() { 
     Mockito.when(service.getMessage("peeskillet")).thenReturn("Hello peeskillet"); 

     Response response = target("message").queryParam("name", "peeskillet").request() 
       .header("X-Header", "blah") 
       .get(); 
     assertEquals(200, response.getStatus()); 
     assertEquals("Hello peeskillet", response.readEntity(String.class)); 
    } 
} 
+0

Vielen Dank für Ihre Antwort. Eine weitere Frage dazu ist, was kann ich tun, wenn ich in meiner Ressource Eigenschaft mit @ Context-Attribut haben? Ich aktualisiere meinen Beitrag mit dem –

+0

Wenn Sie einen Unit-Test ausführen, spotten Sie es wie ich oben beschrieben habe. Wenn Sie einen Integrationstest mit dem Testframework ausführen, müssen Sie ihn so konfigurieren, dass er in einem Servletcontainer ausgeführt wird, damit das HttpServletRequest-Objekt injiziert wird. [Siehe hier] (http://stackoverflow.com/q/28436040/2587435) –

+0

Sieht aus wie die Bindung für mich nicht funktioniert. Ich habe eine Sammelmappe für HttpServletRequest erstellt und einige Haltepunkte eingefügt, und nichts passiert. Ich mache Integrationstest. –