JUnit – Testing REST APIs

In this tutorial, you will learn how to use JUnit to test REST APIs.

REST APIs are a critical component of modern web applications, and testing them ensures that endpoints behave as expected, handle edge cases gracefully, and provide reliable data.

In this tutorial, you will learn how to set up, configure, and execute REST API tests using JUnit, along with best practices for efficient API testing.


Why Test REST APIs?

  • Ensure Correctness: Validate that endpoints return the expected data and status codes.
  • Handle Edge Cases: Verify how APIs behave with invalid inputs, missing parameters, or unexpected conditions.
  • Maintain Stability: Catch regressions when modifying API implementations.
  • Enhance Security: Test for vulnerabilities such as injection attacks or unauthorized access.

Setting Up the Environment

Before testing REST APIs, ensure you have the necessary dependencies and configurations. For example, if you’re using Spring Boot, include the following dependencies in your pom.xml:

</>
Copy
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>io.rest-assured</groupId>
    <artifactId>rest-assured</artifactId>
    <scope>test</scope>
</dependency>

These dependencies include tools like RestTemplate, MockMvc, and RestAssured for API testing.


Basic Example: Using RestTemplate

The RestTemplate class in Spring simplifies making HTTP requests. Let’s test a sample REST endpoint that returns user details:

</>
Copy
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

class RestTemplateTest {

    @Test
    void testGetUser() {
        RestTemplate restTemplate = new RestTemplate();
        String url = "https://jsonplaceholder.typicode.com/users/1";

        ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);

        assertEquals(200, response.getStatusCodeValue(), "Expected HTTP status 200");
        System.out.println(response.getBody());
    }
}

Explanation:

  • HTTP GET Request: The getForEntity() method sends a GET request to the specified URL.
  • Response Validation: The status code and body are validated to ensure the API response is correct.

Advanced Example: Using RestAssured

RestAssured is a popular library for testing REST APIs. It provides a fluent interface for making requests and validating responses:

</>
Copy
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
import org.junit.jupiter.api.Test;

class RestAssuredTest {

    @Test
    void testGetUser() {
        given()
            .baseUri("https://jsonplaceholder.typicode.com")
        .when()
            .get("/users/1")
        .then()
            .statusCode(200)
            .body("name", equalTo("Leanne Graham"))
            .body("address.city", equalTo("Gwenborough"));
    }
}

Explanation:

  • Fluent Interface: The given(), when(), and then() methods make the code readable and expressive.
  • JSON Path Validation: The body() method checks specific fields in the JSON response.

Mocking APIs with MockMvc

If you’re testing a Spring Boot application, MockMvc is an excellent tool for testing controllers without starting the entire application:

</>
Copy
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;

@SpringBootTest
@AutoConfigureMockMvc
class MockMvcTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    void testGetUser() throws Exception {
        mockMvc.perform(get("/api/users/1"))
               .andExpect(status().isOk())
               .andExpect(jsonPath("$.name").value("John Doe"))
               .andExpect(jsonPath("$.email").value("john.doe@example.com"));
    }
}

Key Points:

  • Integration Testing: MockMvc tests your controllers in isolation without starting a server.
  • JSON Path Validation: Validates specific fields in the JSON response.

Testing POST Requests

Let’s test an endpoint that creates a new resource using a POST request:

</>
Copy
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
import org.junit.jupiter.api.Test;

class RestAssuredPostTest {

    @Test
    void testCreateUser() {
        given()
            .baseUri("https://jsonplaceholder.typicode.com")
            .contentType("application/json")
            .body("{ \"name\": \"John Doe\", \"email\": \"john.doe@example.com\" }")
        .when()
            .post("/users")
        .then()
            .statusCode(201)
            .body("name", equalTo("John Doe"))
            .body("email", equalTo("john.doe@example.com"));
    }
}

Here, the given() method specifies the request payload, and post() sends the POST request.


Best Practices for REST API Testing

  • Test All Scenarios: Validate positive cases, negative cases, and edge cases for each endpoint.
  • Automate Assertions: Use libraries like RestAssured or JSON Path for expressive and automated validation.
  • Mock External APIs: For isolated tests, mock external APIs to avoid dependencies on real services.
  • Check Status Codes: Validate HTTP status codes to ensure proper communication.
  • Run Tests Regularly: Integrate API tests into CI/CD pipelines to catch issues early.

Conclusion

JUnit provides a versatile framework for testing REST APIs. With tools like RestTemplate, RestAssured, and MockMvc, you can validate endpoints efficiently and ensure their reliability. By following the examples and best practices outlined in this guide, you can create robust and maintainable API tests, ensuring the quality of your web services.