Das Jersey Test Framework erkunden

Entdecken Sie das Jersey Test Framework

1. Überblick

In diesem Tutorial werfen wir einen Blick auf das Jersey Test Framework und sehen, wie wir es zum schnellen Schreiben von Integrationstests verwenden können.

Wie wir bereits in früheren Artikeln gesehen haben,Jersey is an open source framework for developing RESTful Web Services. Weitere Informationen zu Jersey finden Sie in unserer Einführung zum Erstellen einer API mit Jersey- und Spring-Artikeln -here.

2. Anwendungssetup

Das Jersey Test Framework ist ein Tool, mit dem wir die korrekte Implementierung unserer serverseitigen Komponenten überprüfen können. Wie wir später sehen werden, istit provides a fast and fuss-free way for writing integration tests und kann sehr gut mit unseren HTTP-APIs kommunizieren.

Likewise, it works almost out-of-the-box and it’s easy to integrate with our Maven-based projects. Das Framework basiert hauptsächlich auf JUnit, obwohl es auch mit TestNG verwendet werden kann, wodurch es in fast allen Umgebungen verwendet werden kann.

Im nächsten Abschnitt erfahren Sie, welche Abhängigkeiten wir unserer Anwendung hinzufügen müssen, um das Framework verwenden zu können.

2.1. Maven-Abhängigkeiten

Fügen wir zunächst die Kernabhängigkeit des Jersey Test Framework zu unserenpom.xmlhinzu:


    org.glassfish.jersey.test-framework
    jersey-test-framework-core
    2.27
    test

Wie immer können wir die neueste Version vonMaven Central erhalten.

Fast alle Jersey-Tests verwenden die defacto Grizzly-Testbehälterfabrik, die wir auch hinzufügen müssen:


    org.glassfish.jersey.test-framework.providers
    jersey-test-framework-provider-grizzly2
    2.27
    test

Wieder können wir die neueste Version inMaven Central finden.

3. Anfangen

In diesem nächsten Abschnitt werden die grundlegenden Schritte behandelt, die zum Schreiben eines einfachen Tests erforderlich sind.

Zunächst testen wir die einfache RessourceGreetingsauf unserem Server:

@Path("/greetings")
public class Greetings {

    @GET
    @Path("/hi")
    public String getHiGreeting() {
        return "hi";
    }
}

3.1. Test konfigurieren

Definieren wir nun unsere Testklasse:

public class GreetingsResourceIntegrationTest extends JerseyTest {

    @Override
    protected Application configure() {
        return new ResourceConfig(Greetings.class);
    }
    //...
}

We can see in the above example that to develop a test using the Jersey Test Framework our test needs to subclass JerseyTest.

Als Nächstes überschreiben wir die Methodeconfigure, die eine benutzerdefinierte Ressourcenkonfiguration für unseren Test zurückgibt und nur die RessourceGreetingsenthält. Dies ist natürlich die Ressource, die wir testen möchten.

3.2. Schreiben Sie unseren ersten Test

Beginnen wir mit dem Testen einer einfachen GET-Anfrage über unsere Begrüßungs-API:

@Test
public void givenGetHiGreeting_whenCorrectRequest_thenResponseIsOkAndContainsHi() {
    Response response = target("/greetings/hi").request()
        .get();

    assertEquals("Http Response should be 200: ", Status.OK.getStatusCode(), response.getStatus());
    assertEquals("Http Content-Type should be: ", MediaType.TEXT_HTML, response.getHeaderString(HttpHeaders.CONTENT_TYPE));

    String content = response.readEntity(String.class);
    assertEquals("Content of ressponse is: ", "hi", content);
}

Beachten Sie, dass wir vollen Zugriff auf die HTTP-Antwort haben -so we can do things like checking the status code to make sure the operation was actually successful, or work with the actual body of the response.

Lassen Sie uns genauer erklären, was wir im obigen Beispiel tun:

  1. Senden Sie eine HTTP-GET-Anfrage an "/ greetings / hi".

  2. Überprüfen Sie den HTTP-Statuscode und die Antwortheader für den Inhaltstyp

  3. Testen Sie den Inhalt der Antwort enthält die Zeichenfolge "hi"

4. Testen von GET zum Abrufen von Ressourcen

Nachdem wir nun die grundlegenden Schritte zum Erstellen von Tests gesehen haben. Testen wir die einfache Frucht-API, die wir in den ausgezeichnetenJersey MVC Support articleeingeführt haben.

4.1. Holen Sie sich Plain JSON

Im folgenden Beispiel arbeiten wir mit dem Antworttext als Standard-JSON-Zeichenfolge:

@Test
public void givenFruitExists_whenSearching_thenResponseContainsFruit() {
    final String json = target("fruit/search/strawberry").request()
        .get(String.class);
    assertThat(json, containsString("{\"name\":\"strawberry\",\"weight\":20}"));
}

4.2. Entität anstelle von JSON abrufen

Wir können die Antwort auch direkt einer Ressourcenentitätsklasse zuordnen - zum Beispiel:

   @Test
    public void givenFruitExists_whenSearching_thenResponseContainsFruitEntity() {
        final Fruit entity = target("fruit/search/strawberry").request()
            .get(Fruit.class);

        assertEquals("Fruit name: ", "strawberry", entity.getName());
        assertEquals("Fruit weight: ", Integer.valueOf(20), entity.getWeight());
    }

Dieses Mal geben wir den Java-Typ an, in den die Antwortentität in der Methodegetkonvertiert wird - ein ObjektFruit.

5. POST testen, um Ressourcen zu erstellen

Um eine neue Ressource in unserer API zu erstellen, werden wir die POST-Anforderungen gut nutzen. Im nächsten Abschnitt erfahren Sie, wie Sie diesen Teil unserer API testen.

5.1. Post Plain JSON

Beginnen wir mit der Veröffentlichung eines einfachen JSON-Strings, um die Erstellung einer neuen Fruchtressource zu testen:

@Test
public void givenCreateFruit_whenJsonIsCorrect_thenResponseCodeIsCreated() {
    Response response = target("fruit/created").request()
        .post(Entity.json("{\"name\":\"strawberry\",\"weight\":20}"));

    assertEquals("Http Response should be 201 ", Status.CREATED.getStatusCode(), response.getStatus());
    assertThat(response.readEntity(String.class), containsString("Fruit saved : Fruit [name: strawberry colour: null]"));
}

Im obigen Beispiel verwenden wir die Methodepost, die einen ObjektparameterEntityverwendet. We use the convenient json method to create an entity from the corresponding JSON string.

5.2. Post Entity anstelle von JSON

As we’ve already seen with get requests we can also post a Resource entity class directly - zum Beispiel:

@Test
public void givenCreateFruit_whenFruitIsInvalid_thenResponseCodeIsBadRequest() {
    Fruit fruit = new Fruit("Blueberry", "purple");
    fruit.setWeight(1);

    Response response = target("fruit/create").request(MediaType.APPLICATION_JSON_TYPE)
        .post(Entity.entity(fruit, MediaType.APPLICATION_JSON_TYPE));

    assertEquals("Http Response should be 400 ", 400, response.getStatus());
    assertThat(response.readEntity(String.class), containsString("Fruit weight must be 10 or greater"));
}

Dieses Mal verwenden wir dieentity-Methode, um unsere Fruit-Entität zu veröffentlichen und den Medientyp als JSON anzugeben.

5.3. Formularübermittlung mit POST

In unserem letzten Post-Beispiel sehen wir, wie Sie Formularübermittlungen über eine Post-Anfrage testen können:

@Test
public void givenCreateFruit_whenFormContainsNullParam_thenResponseCodeIsBadRequest() {
    Form form = new Form();
    form.param("name", "apple");
    form.param("colour", null);

    Response response = target("fruit/create").request(MediaType.APPLICATION_FORM_URLENCODED)
        .post(Entity.form(form));

    assertEquals("Http Response should be 400 ", 400, response.getStatus());
    assertThat(response.readEntity(String.class), containsString("Fruit colour must not be null"));
 }

In ähnlicher Weise verwenden wir die KlasseEntity, aber dieses Mal übergeben wir ein Formular, das eine Reihe von Parametern enthält, an unsere Post-Anfrage.

6. Testen anderer HTTP-Verben

Manchmal müssen wir andere HTTP-Endpunkte wie PUT und DELETE testen. This is of course perfectly possible using the Jersey Test Framework.

Sehen wir uns ein einfaches PUT-Beispiel an:

@Test
public void givenUpdateFruit_whenFormContainsBadSerialParam_thenResponseCodeIsBadRequest() {
    Form form = new Form();
    form.param("serial", "2345-2345");

    Response response = target("fruit/update").request(MediaType.APPLICATION_FORM_URLENCODED)
        .put(Entity.form(form));

    assertEquals("Http Response should be 400 ", 400, response.getStatus());
    assertThat(response.readEntity(String.class), containsString("Fruit serial number is not valid"));
}

Sobald wir dierequest-Methode aufgerufen haben, können wir eine beliebige HTTP-Methode für das aktuelle Anforderungsobjekt aufrufen.

7. Zusatzfunktionen

Das Jersey-Testframework enthält eine Reihe zusätzlicher Konfigurationseigenschaften, die beim Debuggen und Testen helfen können.

Im nächsten Beispiel erfahren Sie, wie Sie eine Funktion mit einem bestimmten Namen programmgesteuert aktivieren:

public class FruitResourceIntegrationTest extends JerseyTest {

    @Override
    protected Application configure() {
        enable(TestProperties.LOG_TRAFFIC);
        enable(TestProperties.DUMP_ENTITY);
        //...

Wenn wir unsere getestete Jersey-Anwendung erstellen und konfigurieren. Wir können auch zusätzliche Eigenschaften aktivieren. In diesem Fall aktivieren wir zwei Protokollierungseigenschaften -LOG_TRAFFIC undDUMP_ENTITYwhich will provide useful additional logging and debug information during test runs.

8. Unterstützte Container

Wie bereits erwähnt, ist der Defacto-Container, der beim Schreiben von Tests mit dem Jersey Test Framework verwendet wird, Grizzly. However, a number of other containers are supported:

  • In-Memory-Container

  • HTTP-Server von Oracle JDK

  • Einfacher Container (org.simpleframework.http

  • Anlegebehälter (org.eclipse.jetty)

Weitere Informationen zum Konfigurieren dieser Container finden Sie in der Dokumentationhere.

9. Fazit

Zusammenfassend haben wir in diesem Lernprogramm das Jersey Test Framework untersucht. Zuerst haben wir eingeführt, wie das Jersey Test Framework konfiguriert wird, und dann haben wir gesehen, wie ein Test für eine sehr einfache API geschrieben wird.

Im nächsten Abschnitt wurde beschrieben, wie Tests für verschiedene GET- und POST-API-Endpunkte geschrieben werden. Zuletzt haben wir uns einige zusätzliche Funktionen und die Container angesehen, die das Jersey Test Framework unterstützt.

Wie immer ist der vollständige Quellcode des Artikelsover on GitHub verfügbar.