2016-05-14 2 views
2

Ich baue eine Jersey Web-Anwendung auf Tomcat. Mir fällt es schwer zu verstehen, wie man die App testen kann.Wie kann ich eine Jersey-Webanwendung, die auf Tomcat bereitgestellt wird, in der Unit testen?

Testen der Kerngeschäftslogik (die Nicht-Jersey-Ressourcenklassen) ist möglich, indem Sie einfach die Klassen in meinen Tests instanziieren und Methoden darauf aufrufen (das hat nichts mit Jersey oder Tomcat zu tun).

Aber was ist der richtige Weg zum Unit-Test der Jersey-Ressourcenklassen (d. H. Die Klassen, die URLs zuordnen)?

Muss ich Tomcat laufen lassen? Oder sollte ich die Request- und Response-Objekte verspotten, die Ressourcenklassen in meinen Tests instantiieren und die Mocks meinen Klassen zuführen?

Ich habe über das Testen in Jersey's Website gelesen, aber sie verwenden Grizzly und nicht Tomcat in ihren Beispielen, was anders ist.

Bitte erläutern Sie, wie dies zu tun ist. Beispielcode wäre willkommen.

+1

Das ist nicht Unit-Tests; das ist Integrationstests. Die Unterscheidung ist wichtig. – duffymo

+0

Ich wollte das schreiben, aber der genaue Punkt wurde bereits von @duffymo gemacht. Was Sie für Integrationstest und nicht für Komponententest fragen. – Siddharth

Antwort

2

Wenn Sie nur Einheit testen möchten, müssen Sie keinen Server starten. Wenn Sie eine Dienste (Business-Schicht) oder andere Injektionen wie UriInfo und Dinge dieser Art haben, können Sie nur spotten. Ein ziemlich populärer Rahmen ist Mockito. Im Folgenden finden Sie ein komplettes Beispiel

import javax.inject.Inject; 
import javax.ws.rs.GET; 
import javax.ws.rs.Path; 
import javax.ws.rs.PathParam; 
import javax.ws.rs.core.Response; 

import org.junit.Before; 
import org.junit.Test; 
import org.mockito.Mockito; 

import static org.hamcrest.CoreMatchers.instanceOf; 
import static org.hamcrest.CoreMatchers.is; 
import static org.junit.Assert.assertThat; 

/** 
* Beside Jersey dependencies, you will need Mockito. 
* 
* <dependency> 
*  <groupId>org.mockito</groupId> 
*  <artifactId>mockito-core</artifactId> 
*  <version>1.10.19</version> 
* </dependency> 
* 
* @author Paul Samsotha 
*/ 
public class SomethingResourceUnitTest { 

    public static interface SomeService { 
     String getSomethingById(int id); 
    } 

    @Path("something") 
    public static class SomethingResource { 

     private final SomeService service; 

     @Inject 
     public SomethingResource(SomeService service) { 
      this.service = service; 
     } 

     @GET 
     @Path("{id}") 
     public Response getSomethingById(@PathParam("id") int id) { 
      String result = service.getSomethingById(id); 
      return Response.ok(result).build(); 
     } 
    } 

    private SomethingResource resource; 
    private SomeService service; 

    @Before 
    public void setUp() { 
     service = Mockito.mock(SomeService.class); 
     resource = new SomethingResource(service); 
    } 

    @Test 
    public void testGetSomethingById() { 
     Mockito.when(service.getSomethingById(Mockito.anyInt())).thenReturn("Something"); 

     Response response = resource.getSomethingById(1); 
     assertThat(response.getStatus(), is(200)); 
     assertThat(response.getEntity(), instanceOf(String.class)); 
     assertThat((String)response.getEntity(), is("Something")); 
    } 
} 

Siehe auch:


Wenn Sie eine Integration Test ausgeführt werden soll, persönlich sehe ich nicht viel Unterschied, ob Sie einen Grizzly-Container gegen einen T laufen lassen oder nicht omcat container, solange Sie in Ihrer Anwendung nichts Spezifisches für Tomcat verwenden.

Die Verwendung der Jersey Test Framework ist eine gute Option für Integrationstests, sie haben jedoch keinen Tomcat-Provider. Es gibt nur Grizzly, In-Memory und Jetty. Wenn Sie keine Servlet-APIs wie HttpServletRequest oder ServletContext usw. verwenden, kann der In-Memory-Anbieter eine praktikable Lösung sein. Es wird Ihnen schnellere Testzeit geben.

Siehe auch:


Wenn Sie müssen Tomcat verwenden, können Sie Ihre eigene eingebettete Tomcat laufen. Ich habe nicht viel Dokumentation gefunden, aber es gibt eine example in DZone. Ich benutze nicht wirklich das eingebettete Tomcat, aber gehen von dem Beispiel in der vorherigen Verbindung, können Sie etwas wie das folgende haben (das zum Funktionieren getestet worden ist)

import java.io.File; 

import javax.inject.Inject; 
import javax.ws.rs.GET; 
import javax.ws.rs.Path; 
import javax.ws.rs.PathParam; 
import javax.ws.rs.client.ClientBuilder; 
import javax.ws.rs.core.Response; 

import org.apache.catalina.Context; 
import org.apache.catalina.startup.Tomcat; 
import org.glassfish.hk2.utilities.binding.AbstractBinder; 
import org.glassfish.jersey.server.ResourceConfig; 
import org.glassfish.jersey.servlet.ServletContainer; 
import org.junit.After; 
import org.junit.Before; 
import org.junit.Test; 

import static org.hamcrest.CoreMatchers.is; 
import static org.junit.Assert.assertThat; 

/** 
* Aside from the Jersey dependencies, you will need the following 
* Tomcat dependencies. 
* 
* <dependency> 
*  <groupId>org.apache.tomcat.embed</groupId> 
*  <artifactId>tomcat-embed-core</artifactId> 
*  <version>8.5.0</version> 
*  <scope>test</scope> 
* </dependency> 
* <dependency> 
*  <groupId>org.apache.tomcat.embed</groupId> 
*  <artifactId>tomcat-embed-logging-juli</artifactId> 
*  <version>8.5.0</version> 
*  <scope>test</scope> 
* </dependency> 
* 
* See also https://dzone.com/articles/embedded-tomcat-minimal 
*  
* @author Paul Samsotha 
*/ 
public class SomethingResourceTomcatIntegrationTest { 

    public static interface SomeService { 
     String getSomethingById(int id); 
    } 

    public static class SomeServiceImpl implements SomeService { 
     @Override 
     public String getSomethingById(int id) { 
      return "Something"; 
     } 
    } 

    @Path("something") 
    public static class SomethingResource { 

     private final SomeService service; 

     @Inject 
     public SomethingResource(SomeService service) { 
      this.service = service; 
     } 

     @GET 
     @Path("{id}") 
     public Response getSomethingById(@PathParam("id") int id) { 
      String result = service.getSomethingById(id); 
      return Response.ok(result).build(); 
     } 
    } 

    private Tomcat tomcat; 

    @Before 
    public void setUp() throws Exception { 
     tomcat = new Tomcat(); 
     tomcat.setPort(8080); 

     final Context ctx = tomcat.addContext("/", new File(".").getAbsolutePath()); 

     final ResourceConfig config = new ResourceConfig(SomethingResource.class) 
       .register(new AbstractBinder() { 
        @Override 
        protected void configure() { 
         bind(SomeServiceImpl.class).to(SomeService.class); 
        } 
       }); 
     Tomcat.addServlet(ctx, "jersey-test", new ServletContainer(config)); 
     ctx.addServletMapping("/*", "jersey-test"); 

     tomcat.start(); 
    } 

    @After 
    public void tearDown() throws Exception { 
     tomcat.stop(); 
    } 

    @Test 
    public void testGetSomethingById() { 
     final String baseUri = "http://localhost:8080"; 
     final Response response = ClientBuilder.newClient() 
       .target(baseUri).path("something").path("1") 
       .request().get(); 
     assertThat(response.getStatus(), is(200)); 
     assertThat(response.readEntity(String.class), is("Something")); 
    } 
} 
Verwandte Themen