TestRestTemplate for API testing in JUnit - Build an Automation Script
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.
Now add data-driven testing to verify GET /api/users returns expected fields for 3 different endpoints: /api/users, /api/admins, /api/guests
Practice
TestRestTemplate in JUnit testing?Solution
Step 1: Understand the role of TestRestTemplate
TestRestTemplate is designed to send actual HTTP requests to REST APIs during integration tests.Step 2: Compare with other options
Mocking databases, generating test data, or creating UI components are unrelated to TestRestTemplate's purpose.Final Answer:
To send real HTTP requests to test REST APIs -> Option BQuick Check:
TestRestTemplate = Real HTTP requests [OK]
- Confusing TestRestTemplate with mocking tools
- Thinking it generates test data
- Assuming it tests UI components
TestRestTemplate in a Spring Boot test class?Solution
Step 1: Identify correct Spring Boot injection
In Spring Boot tests,@Autowiredis used to inject TestRestTemplate automatically.Step 2: Evaluate other options
Creating a new instance manually or using@InjectMocksis incorrect for TestRestTemplate injection in Spring Boot tests.Final Answer:
@Autowired private TestRestTemplate restTemplate; -> Option AQuick Check:
Use @Autowired for TestRestTemplate injection [OK]
- Manually instantiating TestRestTemplate
- Using @InjectMocks instead of @Autowired
- Leaving the variable null without injection
TestRestTemplate:
ResponseEntity<String> response = restTemplate.getForEntity("/api/users/1", String.class);
int statusCode = response.getStatusCodeValue();
String body = response.getBody();
If the API returns HTTP 200 with body "User Found", what will be the values of statusCode and body?Solution
Step 1: Understand getForEntity behavior
getForEntity sends a GET request and returns the full response including status and body.Step 2: Match API response to variables
Since API returns 200 and "User Found", statusCode will be 200 and body will be "User Found".Final Answer:
statusCode = 200, body = "User Found" -> Option CQuick Check:
API 200 + body = statusCode 200 & body "User Found" [OK]
- Assuming body is null on success
- Confusing status codes with error codes
- Ignoring response body content
TestRestTemplate:
@Autowired
private TestRestTemplate restTemplate;
@Test
public void testGetUser() {
ResponseEntity<String> response = restTemplate.getForEntity("/api/users/", String.class);
assertEquals(200, response.getStatusCodeValue());
}
What is the likely problem with this test?Solution
Step 1: Analyze the request URL
The URL "/api/users/" lacks a specific user ID, so the endpoint may not exist or return a list, not a single user.Step 2: Understand the assertion failure cause
Expecting status 200 for a missing user ID endpoint may cause a 404 error, failing the test.Final Answer:
The URL is missing a user ID, causing a 404 error -> Option AQuick Check:
Missing ID in URL causes 404, not 200 [OK]
- Assuming URL without ID returns 200
- Wrong assertion status code
- Thinking autowiring is the issue
/api/users that creates a user and returns HTTP 201 with the created user JSON. Which TestRestTemplate method and assertion combination correctly tests this?Solution
Step 1: Identify correct HTTP method for creation
POST is used to create resources, sopostForEntityis appropriate for sending the user object.Step 2: Validate expected response and assertions
The API returns 201 Created with user JSON, so assert status 201 and check response body contains user data.Final Answer:
Use postForEntity with user object, then assert status 201 and response body contains user data -> Option DQuick Check:
POST + postForEntity + assert 201 + check body [OK]
- Using GET instead of POST for creation
- Asserting wrong status codes
- Ignoring response body validation
Ready to prove it?
Pass the test and this pattern moves unknown
