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?
@SpringBootTest
loads the complete Spring Boot application context, while@WebMvcTest
only loads the web layer components (controllers, filters, etc.).@WebMvcTest
is faster but does not test the entire application context. Using@SpringBootTest
withwebEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
starts 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@Configuration
class annotated with@TestConfiguration
and provide mock implementations of your services.