0
0
JUnittesting~15 mins

TestRestTemplate for API testing in JUnit - Build an Automation Script

Choose your learning style9 modes available
Verify GET /api/users returns list of users
Preconditions (2)
Step 1: Send a GET request to http://localhost:8080/api/users using TestRestTemplate
Step 2: Capture the response
Step 3: Verify the HTTP status code is 200
Step 4: Verify the response body is a JSON array
Step 5: Verify the first user object has 'id', 'name', and 'email' fields
✅ Expected Result: Response status is 200 OK and response body contains a JSON array with user objects having id, name, and email fields
Automation Requirements - JUnit 5 with Spring Boot Test
Assertions Needed:
HTTP status code is 200
Response body is not null
Response body contains expected JSON structure
Best Practices:
Use @SpringBootTest with webEnvironment RANDOM_PORT
Inject TestRestTemplate bean
Use ResponseEntity<T> to capture response
Use assertions from org.junit.jupiter.api.Assertions
Avoid hardcoding URLs, use @LocalServerPort for port
Automated Solution
JUnit
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.ResponseEntity;
import org.springframework.boot.test.web.client.TestRestTemplate;
import static org.junit.jupiter.api.Assertions.*;
import java.util.List;
import java.util.Map;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class UserApiTest {

    @LocalServerPort
    private int port;

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void testGetUsersReturnsList() {
        String url = "http://localhost:" + port + "/api/users";
        ResponseEntity<List> response = restTemplate.getForEntity(url, List.class);

        // Assert status code 200
        assertEquals(200, response.getStatusCodeValue(), "Status code should be 200");

        // Assert body is not null
        List<?> users = response.getBody();
        assertNotNull(users, "Response body should not be null");

        // Assert body is a list and has at least one user
        assertFalse(users.isEmpty(), "User list should not be empty");

        // Assert first user has keys id, name, email
        Object firstUser = users.get(0);
        assertTrue(firstUser instanceof Map, "User should be a Map");
        Map<?, ?> userMap = (Map<?, ?>) firstUser;
        assertTrue(userMap.containsKey("id"), "User should have 'id'");
        assertTrue(userMap.containsKey("name"), "User should have 'name'");
        assertTrue(userMap.containsKey("email"), "User should have 'email'");
    }
}

This test class uses @SpringBootTest with webEnvironment = RANDOM_PORT to start the server on a random port to avoid conflicts.

The @LocalServerPort injects the actual port number used, so the test builds the URL dynamically.

TestRestTemplate is injected to send HTTP requests easily.

The test method sends a GET request to /api/users and captures the response as a List of users.

Assertions check that the status code is 200, the response body is not null, the list is not empty, and the first user object contains the expected keys id, name, and email.

This approach ensures the test is reliable, readable, and follows Spring Boot testing best practices.

Common Mistakes - 4 Pitfalls
Hardcoding the server port instead of using @LocalServerPort
Not checking the HTTP status code before accessing the response body
Using raw Object or String for response body without proper type
Not using @SpringBootTest with webEnvironment RANDOM_PORT
Bonus Challenge

Now add data-driven testing to verify GET /api/users returns expected fields for 3 different endpoints: /api/users, /api/admins, /api/guests

Show Hint