This tutorial explains how to write integration tests for an REST API. It uses a public REST API and tests it.

1. Integration tests for a REST API

In this tutorial you create software test to call an REST API. It is an integration test, as it test a system. It is a black box test, as it test a system from the outside.

Your test for a REST resource check:

  • the HTTP response code

  • the HTTP resonse headers

  • the payload (JSON, XML)

2. Exercise: Integration tests for the Github API

Create a new Maven or Gradle project named com.vogella.integrationtests.

2.1. Check the status code

Write a test using the java.net.http.HttpClient to make a get call to the URL.

HINT: see https://www.vogella.com/tutorials/JavaHttpClient/article.html in case you are not familiar with the Java HttpClient.

OPTIONAL: use AssertJ for the assert statements, e.g. by adding it to your Gradle file.

testImplementation 'org.assertj:assertj-core:3.20.2'
package com.vogella.integrationtests;

import static org.assertj.core.api.Assertions.assertThat;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;

import org.junit.jupiter.api.Test;

class GithubIntegrationTests {

    @Test
    void ensureThatUserAPICallReturnStatusCode200() throws Exception {
        HttpClient client = HttpClient.newBuilder().build();
        HttpRequest request = HttpRequest.newBuilder().uri(URI.create("https://api.github.com/users/vogella")).build();
        HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
        fail("FIXME");

    }

    @Test
    @DisplayName("Ensures that the content type starts with application/json")
    void ensureThatJsonIsReturnedAsContentType() throws Exception {
        HttpClient client = HttpClient.newBuilder().build();
        HttpRequest request = HttpRequest.newBuilder().uri(URI.create("https://api.github.com/users/vogella")).build();
        HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
        fail("FIXME");
        // HINT Use response.headers()

    }

    @Test
    @DisplayName ("Ensure that the JSON for the user vogella contains a reference to the Twitter user")
    void ensureJsonContainsTwitterHandler() throws Exception {
        HttpClient client = HttpClient.newBuilder().build();
        HttpRequest request = HttpRequest.newBuilder().uri(URI.create("https://api.github.com/users/vogella")).build();
        HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
        fail("FIXME");

    }
}

2.2. Solution

Solution
package com.vogella.integrationtests;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import java.util.Optional;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

class GithubIntegrationTests {

    @Test
    void ensureThatUserAPICallReturnStatusCode200() throws Exception {
        HttpClient client = HttpClient.newBuilder().build();
        HttpRequest request = HttpRequest.newBuilder().uri(URI.create("https://api.github.com/users/vogella")).build();
        HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
        assertThat(response.statusCode()).isEqualTo(200);

    }

    @Test
    @DisplayName("Ensures that the content type starts with application/json")
    void ensureThatJsonIsReturnedAsContentType() throws Exception {
        HttpClient client = HttpClient.newBuilder().build();
        HttpRequest request = HttpRequest.newBuilder().uri(URI.create("https://api.github.com/users/vogella")).build();
        HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
        Optional<String> firstValue = response.headers().firstValue("Content-Type");
        String string = firstValue.get();
        assertThat(string).startsWith("application/json");
    }

    @Test
    @DisplayName ("Ensure that the JSON for the user vogella contains a reference to the Twitter user")
    void ensureJsonContainsTwitterHandler() throws Exception {
        HttpClient client = HttpClient.newBuilder().build();
        HttpRequest request = HttpRequest.newBuilder().uri(URI.create("https://api.github.com/users/vogella")).build();
        HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
        String body = response.body();
        // For easy to see the output
        System.out.println(body);
        assertTrue(body.contains("twitter_username\":\"vogella\""));
        // TODO check for the twitter handler
    }
}

3. Optional Exercise: Integration tests for the Stackoverflow API

Re-use or create a Maven or Gradle project named com.vogella.integrationtests.

Write an unit test to ensure that at least one question has been posted with the topic junit5.

Use the dynamic test creation to create dynamically tests.

4. Conclusion

In this tutorial you learned how easy it is to write integration tests for REST APIs using Junit 5 and the HttpClient from Java 11.

You find the example as Gradle project on Github.