Java > Testing in Java > Integration Testing > Spring Boot Test
Spring Boot Integration Test with TestRestTemplate
This snippet demonstrates a Spring Boot integration test using TestRestTemplate to test a REST endpoint. Integration tests verify that different parts of your application work correctly together. This example tests a simple controller that returns a greeting.
Project Setup
First, ensure you have a Spring Boot project set up with a basic REST controller. Include the spring-boot-starter-web and spring-boot-starter-test dependencies in your pom.xml or build.gradle file. The spring-boot-starter-test dependency provides testing utilities, including TestRestTemplate.
Example Controller
This is a simple REST controller with a single endpoint, /greeting, that accepts a name parameter and returns a greeting.
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GreetingController {
@GetMapping("/greeting")
public String greeting(@RequestParam(value = "name", defaultValue = "World") String name) {
return "Hello, " + name + "!";
}
}
Integration Test
This integration test uses @SpringBootTest to start the Spring Boot application with a random port. TestRestTemplate is autowired to make HTTP requests to the running application. The tests verify that the /greeting endpoint returns the expected response with both the default and custom names.
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import static org.junit.jupiter.api.Assertions.assertEquals;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class GreetingControllerIntegrationTest {
@LocalServerPort
private int port;
@Autowired
private TestRestTemplate restTemplate;
@Test
public void greetingShouldReturnDefaultMessage() {
ResponseEntity<String> response = restTemplate.getForEntity("http://localhost:" + port + "/greeting", String.class);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals("Hello, World!", response.getBody());
}
@Test
public void greetingShouldReturnCustomMessage() {
ResponseEntity<String> response = restTemplate.getForEntity("http://localhost:" + port + "/greeting?name=Test", String.class);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals("Hello, Test!", response.getBody());
}
}
Concepts Behind the Snippet
This snippet showcases integration testing in Spring Boot, which involves testing the interaction between different components of the application. It verifies that the controller handles requests correctly and returns the expected responses. Key concepts include using @SpringBootTest to start the application context, TestRestTemplate to make HTTP requests, and assertions to validate the responses.
Real-Life Use Case Section
In a real-world application, you might use integration tests to verify the interaction between your controllers, services, and data repositories. For example, you could test that a controller correctly saves data to a database via a service. This ensures that all the layers of your application work together as expected.
Best Practices
Interview Tip
When discussing integration testing in Spring Boot, be prepared to explain the difference between unit and integration tests. Unit tests focus on individual components in isolation, while integration tests verify the interaction between multiple components.
When to use them
Integration tests are best used when you want to verify that different parts of your application work together correctly. This is particularly useful for testing complex interactions between controllers, services, and databases. They help catch issues that might not be apparent during unit testing.
Memory footprint
Integration tests generally have a larger memory footprint than unit tests because they start the Spring Boot application context. However, the memory usage is usually manageable, especially when tests are properly scoped and configured.
Alternatives
Alternatives to TestRestTemplate include using WebTestClient (for reactive applications) or mocking the underlying components to perform more isolated tests. Also consider using tools like Selenium for end-to-end testing.
Pros
Cons
FAQ
-
What is the difference between @SpringBootTest and @WebMvcTest?
@SpringBootTestloads the complete Spring Boot application context, while@WebMvcTestonly loads the web layer components (controllers, filters, etc.).@WebMvcTestis faster but does not test the entire application context. Using@SpringBootTestwithwebEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORTstarts the application on a random port and enables full integration testing. -
How do I mock external services in an integration test?
You can use libraries like Mockito to mock external services or create a test configuration with mock beans to replace the actual service implementations. For example, create a@Configurationclass annotated with@TestConfigurationand provide mock implementations of your services.