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"));
}
}
Das ist nicht Unit-Tests; das ist Integrationstests. Die Unterscheidung ist wichtig. – duffymo
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