Spring Boot 3.1, the latest version of the popular Java-based framework for building stand-alone, production-grade applications, introduces improved support for development-time containers. This new feature was the focus of a recent livestream by Josh Long, a Spring developer advocate, on his YouTube channel "Coffee + Software with Josh Long." In addition, a blog post on the official Spring website titled "Spring Boot 3.1's ConnectionDetails
abstraction" provides further insights into this new feature.
Testcontainers is an open-source Java library that provides lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container. It is primarily used for integration testing, where you need to ensure that your application correctly interacts with an external system.
While Testcontainers was supported in previous versions of Spring Boot, its integration was not as seamless as it could be. Spring Boot 3.1 has addressed this issue by introducing a new @ServiceConnection
annotation. This annotation simplifies the process of integration testing with Testcontainers by reducing the amount of code required and avoiding the "stringly" typed coupling between integration tests and Spring Boot auto-configurations. Consider the following example of how developers can use the @ServiceConnection
annotation:
@ServiceConnection
public static PostgreSQLContainer<?> db = new PostgreSQLContainer<>("postgres:13")
.withDatabaseName("test")
.withUsername("test")
.withPassword("test");
The second major feature introduced in Spring Boot 3.1 is the use of Testcontainers at development time. This feature allows developers to start Testcontainers in their production code and configure properties to connect to those containers. However, this approach requires the Testcontainers dependency to be on the compile classpath, which may be included in the fat JAR. Spring Boot 3.1 offers a better way by keeping the Testcontainers dependency in the test
scope and creating a new main
method inside the test code. Consider the following example:
import org.springframework.boot.SpringApplication;
public class TestMyApplication {
public static void main(String[] args) {
SpringApplication.from(MyApplication::main).run(args);
}
}
This test-main
method utilizes the new SpringApplication.from
method to delegate to the "real" main method used in production code.
Developers now have the ability to create a @TestConfiguration
which defines beans for the Testcontainers needed while developing their application. Consider the following example:
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.context.annotation.Bean;
@TestConfiguration(proxyBeanMethods = false)
public class MyContainersConfiguration {
@Bean
@ServiceConnection
Neo4jContainer<?> neo4jContainer (){
return new Neo4jContainer<>("neo4j:5");
}
}
Spring Boot 3.1 manages the lifecycle of the containers, starting them on application start-up and shutting them down when the application is stopped. This feature can be used from the IDE or from the terminal using the Spring Boot plugins for Gradle and Maven.
The YouTube video provides further insights into the use of Docker Compose and Testcontainers for establishing development-time containers. In the video, Josh Long illustrates the process of creating a main method for Testcontainers and setting up a configuration for MongoDB using Testcontainers. The benefits of these features are highlighted, such as enhanced consistency and simplified setup for development environments, along with more detailed control over the lifecycle of infrastructure for tests.
These enhancements in Spring Boot 3.1 aim to simplify the process of setting up and managing dependencies for development environments, making it easier for new engineers to start contributing to a project. The improved support for Testcontainers and development-time containers in Spring Boot 3.1 is a significant step forward in making the development process more efficient and streamlined.
For more information on how to use Testcontainers with Spring Boot, developers can refer to the official Spring Boot documentation.