Spring Boot Testcontainers Example
In this tutorial, we will create a sample Spring Boot API that uses MongoDB as its database and then demonstrate how to use Testcontainers to write integration tests for the API. Testcontainers is a powerful Java library that allows you to spin up and manage Docker containers during your test runs, making it ideal for testing applications that rely on external services like databases.
Prerequisites
Before getting started, make sure you have the following prerequisites:
- Java Development Kit (JDK) 8 or higher installed on your system.
- Apache Maven or Gradle installed (we will use Maven in this tutorial).
- Docker installed and running on your system.
Create a Spring Boot Application
Let’s start by creating a new Spring Boot project. You can use the Spring Initializer, a web-based tool, or your preferred IDE to create the project. Make sure to include the following dependencies:
- Spring Web
- Spring Data MongoDB
- Lombok (optional but useful for reducing boilerplate code)
For this tutorial, we’ll name our project “SpringBootTestcontainersExample.”
Implement a Sample API
Next, let’s implement a simple RESTful API that interacts with a MongoDB database. Create a Book
class representing a book entity:
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Data
@Document
public class Book {
@Id
private String id;
private String title;
private String author;
}
Now, create a repository for the Book
class:
import org.springframework.data.mongodb.repository.MongoRepository;
public interface BookRepository extends MongoRepository<Book, String> {
}
Next, create a controller to handle HTTP requests:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/books")
public class BookController {
private final BookRepository bookRepository;
@Autowired
public BookController(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
@GetMapping
public List<Book> getAllBooks() {
return bookRepository.findAll();
}
@PostMapping
public Book createBook(@RequestBody Book book) {
return bookRepository.save(book);
}
}
Your basic Spring Boot application with MongoDB integration is now ready.
Add Testcontainers Dependency
To use Testcontainers in your project, you need to add the testcontainers
dependency to your pom.xml
(if using Maven) or build.gradle
(if using Gradle). Here’s the Maven dependency:
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.16.3</version> <!-- Replace with the latest version -->
<scope>test</scope>
</dependency>
Make sure to use the latest version of Testcontainers.
Write Integration Tests
Now, let’s write integration tests using Testcontainers to ensure our Spring Boot API interacts correctly with a MongoDB container.
Create a test class in the src/test/java
directory (e.g., BookControllerIntegrationTest.java
) and add the following code:
import org.junit.jupiter.api.*;
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.boot.web.server.LocalServerPort;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.testcontainers.containers.MongoDBContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@Testcontainers
public class BookControllerIntegrationTest {
@LocalServerPort
private int port;
@Autowired
private MockMvc mockMvc;
@Container
private static final MongoDBContainer mongoDBContainer = new MongoDBContainer(DockerImageName.parse("mongo:latest"))
.withExposedPorts(27017);
@BeforeAll
public static void setUp() {
mongoDBContainer.start();
}
@AfterAll
public static void tearDown() {
mongoDBContainer.stop();
}
@Test
public void testCreateBook() throws Exception {
String requestBody = "{\"title\":\"Test Book\",\"author\":\"Test Author\"}";
mockMvc.perform(MockMvcRequestBuilders.post("http://localhost:" + port + "/books")
.content(requestBody)
.contentType("application/json"))
.andExpect(status().isOk());
mockMvc.perform(MockMvcRequestBuilders.get("http://localhost:" + port + "/books"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.length()").value(1))
.andExpect(jsonPath("$[0].title").value("Test Book"))
.andExpect(jsonPath("$[0].author").value("Test Author"));
}
}
In this test class:
- We use
@Testcontainers
to indicate that we will be using Testcontainers in our tests. - We create a MongoDB container using
MongoDBContainer
and expose port 27017. - In the
setUp
andtearDown
methods, we start and stop the MongoDB container. - The
testCreateBook
method sends a POST request to create a book and then verifies that the book was successfully created by sending a GET request to retrieve all books.
Run the Tests
You can now run your integration tests by executing the following command from the project’s root directory:
mvn test
Testcontainers will automatically start a MongoDB Docker container, run your tests, and then clean up the container after the tests are finished.
Congratulations! You have successfully created a Spring Boot API, integrated MongoDB, and used Testcontainers to write integration tests for your application.
This tutorial provides a basic example, but you can extend it to test other parts of your application that rely on external services using Testcontainers.