Testen Sie eine REST-API mit Java

Testen Sie eine REST-API mit Java

1. Überblick

Dieses Tutorial konzentriert sich auf die Grundprinzipien und Mechanismen vontesting a REST API with live Integration Tests (mit einer JSON-Nutzlast).

# # Das Hauptziel besteht darin, eine Einführung in das Testen der grundlegenden Korrektheit der API zu geben. Für die Beispiele wird die neueste Version vonGitHub REST API verwendet.

Bei einer internen Anwendung wird diese Art von Test normalerweise als später Schritt in einem kontinuierlichen Integrationsprozess ausgeführt und verbraucht die REST-API, nachdem sie bereits bereitgestellt wurde.

Beim Testen einer REST-Ressource gibt es normalerweise einige orthogonale Zuständigkeiten, auf die sich die Tests konzentrieren sollten:

  • die HTTPresponse code

  • andere HTTPheaders in der Antwort

  • diepayload (JSON, XML)

Each test should only focus on a single responsibility and include a single assertion. Die Konzentration auf eine klare Trennung hat immer Vorteile, aber bei dieser Art von Black-Box-Tests ist dies noch wichtiger, da die allgemeine Tendenz darin besteht, am Anfang komplexe Testszenarien zu schreiben.

Ein weiterer wichtiger Aspekt der Integrationstests ist die Einhaltung derSingle Level of Abstraction Principle - die Logik innerhalb eines Tests sollte auf einer hohen Ebene geschrieben werden. Details wie das Erstellen der Anforderung, das Senden der HTTP-Anforderung an den Server, das Behandeln von E / A usw. sollten nicht direkt, sondern über Dienstprogrammmethoden erfolgen.

Weitere Lektüre:

Integrationstests im Frühjahr

Eine Kurzanleitung zum Schreiben von Integrationstests für eine Spring-Webanwendung.

Read more

Testen im Frühjahr Boot

Erfahren Sie, wie der Spring Boot das Testen unterstützt, um Unit-Tests effizient zu schreiben.

Read more

Ein Leitfaden für REST-versicherte

Lernen Sie die Grundlagen von REST-assured kennen - eine Bibliothek, die das Testen und Validieren von REST-APIs vereinfacht.

Read more

2. Testen des Statuscodes

@Test
public void givenUserDoesNotExists_whenUserInfoIsRetrieved_then404IsReceived()
  throws ClientProtocolException, IOException {

    // Given
    String name = RandomStringUtils.randomAlphabetic( 8 );
    HttpUriRequest request = new HttpGet( "https://api.github.com/users/" + name );

    // When
    HttpResponse httpResponse = HttpClientBuilder.create().build().execute( request );

    // Then
    assertThat(
      httpResponse.getStatusLine().getStatusCode(),
      equalTo(HttpStatus.SC_NOT_FOUND));
}

Dies ist ein ziemlich einfacher Test -it verifies that a basic happy path is working, ohne die Testsuite zu komplex zu gestalten.

Wenn dies aus irgendeinem Grund fehlschlägt, ist es nicht erforderlich, einen anderen Test für diese URL zu suchen, bis dies behoben ist.

3. Testen des Medientyps

@Test
public void
givenRequestWithNoAcceptHeader_whenRequestIsExecuted_thenDefaultResponseContentTypeIsJson()
  throws ClientProtocolException, IOException {

   // Given
   String jsonMimeType = "application/json";
   HttpUriRequest request = new HttpGet( "https://api.github.com/users/eugenp" );

   // When
   HttpResponse response = HttpClientBuilder.create().build().execute( request );

   // Then
   String mimeType = ContentType.getOrDefault(response.getEntity()).getMimeType();
   assertEquals( jsonMimeType, mimeType );
}

Dadurch wird sichergestellt, dass die Antwort tatsächlich JSON-Daten enthält.

Wie Sie vielleicht bemerkt haben,we’re following a logical progression of tests - zuerst der Antwortstatuscode (um sicherzustellen, dass die Anforderung in Ordnung war), dann der Medientyp der Antwort, und erst im nächsten Test werden wir die tatsächliche JSON-Nutzlast untersuchen.

4. Testen der JSON-Nutzlast

@Test
public void
  givenUserExists_whenUserInformationIsRetrieved_thenRetrievedResourceIsCorrect()
  throws ClientProtocolException, IOException {

    // Given
    HttpUriRequest request = new HttpGet( "https://api.github.com/users/eugenp" );

    // When
    HttpResponse response = HttpClientBuilder.create().build().execute( request );

    // Then
    GitHubUser resource = RetrieveUtil.retrieveResourceFromResponse(
      response, GitHubUser.class);
    assertThat( "eugenp", Matchers.is( resource.getLogin() ) );
}

In diesem Fall weiß ich, dass die Standarddarstellung der GitHub-Ressourcen JSON ist, aber normalerweise sollte der Header der Antwort von ++ (Content-Type) zusammen mit dem Header vonAcceptder Anforderung getestet werden - fragt der Client für eine bestimmte Art der Darstellung überAccept, die der Server berücksichtigen sollte.

5. Dienstprogramme zum Testen

Wir werden Jackson 2 verwenden, um den unformatierten JSON-String in eine typsichere Java-Entität zu entfernen:

public class GitHubUser {

    private String login;

    // standard getters and setters
}

Wir verwenden nur ein einfaches Dienstprogramm, um die Tests sauber, lesbar und auf einem hohen Abstraktionsniveau zu halten:

public static  T retrieveResourceFromResponse(HttpResponse response, Class clazz)
  throws IOException {

    String jsonFromResponse = EntityUtils.toString(response.getEntity());
    ObjectMapper mapper = new ObjectMapper()
      .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    return mapper.readValue(jsonFromResponse, clazz);
}

Beachten Sie, dassJackson is ignoring unknown properties ist, dass die GitHub-API unseren Weg sendet - das liegt einfach daran, dass die Darstellung einer Benutzerressource auf GitHub ziemlich komplex wird - und wir brauchen hier keine dieser Informationen.

6. Abhängigkeiten

Die Dienstprogramme und Tests verwenden die folgenden Bibliotheken, die alle in Maven Central verfügbar sind:

7. Fazit

Dies ist nur ein Teil dessen, was die vollständige Integrationstestsuite sein sollte. Die Tests konzentrieren sich aufensuring basic correctness for the REST API, ohne auf komplexere Szenarien einzugehen.

Beispielsweise wird Folgendes nicht behandelt: Erkennbarkeit der API, Verwendung verschiedener Darstellungen für dieselbe Ressource usw.

[.iframe-fluid] ##

Die Implementierung all dieser Beispiele und Codefragmente finden Sie inover on Github - dies ist ein Maven-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein, wie es ist.