In Spring Boot, we can use @DynamicPropertySource to dynamically register or override property values in the ApplicationContext
for integration tests.
Tables of contents:
- 1. Testing with ApplicationContextInitializer
- 2. Testing with @DynamicPropertySource
- 3. Testing with Spring Boot 3.1 and @ServiceConnection
- 4. Download Source Code
- 5. References
P.S. The @DynamicPropertySource
feature is available from Spring Framework 5.2.5 and Spring Boot 2.3.1 onwards.
1. Testing with ApplicationContextInitializer
Before Spring 5.2.5, it was necessary to use @ContextConfiguration
and ApplicationContextInitializer
to set up dynamic property values for integration tests.
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ContextConfiguration(initializers = BookRepositoryDynamicPropertyTest.Initializer.class)
@Testcontainers
public class BookRepositoryDynamicPropertyTest {
@Autowired
private BookRepository bookRepository;
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>(
"postgres:15-alpine"
);
// register dynamic properties like this
static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
TestPropertyValues.of(
"spring.datasource.url=" + postgres.getJdbcUrl(),
"spring.datasource.username=" + postgres.getUsername(),
"spring.datasource.password=" + postgres.getPassword()
).applyTo(applicationContext);
}
}
}
2. Testing with @DynamicPropertySource
Spring 5.2.5+ introduced the @DynamicPropertySource
annotation to improve the registration of the dynamic property values. The following example demonstrates how to use @DynamicPropertySource
to register dynamic data source properties into integration tests using @Testcontainers.
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Testcontainers
public class BookRepositoryDynamicPropertyTest {
@Autowired
private BookRepository bookRepository;
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>(
"postgres:15-alpine"
);
// no more ApplicationContextInitializer
@DynamicPropertySource
static void configureProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgres::getJdbcUrl);
registry.add("spring.datasource.username", postgres::getUsername);
registry.add("spring.datasource.password", postgres::getPassword);
}
@Test
public void testEmptyList() {
List<Book> result = bookRepository.findAll();
assertEquals(0, result.size());
}
}
3. Testing with Spring Boot 3.1 and @ServiceConnection
Spring Boot 3.1 introduced @ServiceConnection to enable the Spring Boot’s auto-configuration to automatically use the service connection details to connect to a remote service (Testcontainers).
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Testcontainers
public class BookRepositoryDynamicPropertyTest {
@Autowired
private BookRepository bookRepository;
@Container
@ServiceConnection // no more @DynamicPropertySource
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>(
"postgres:15-alpine"
);
/*@DynamicPropertySource
static void configureProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgres::getJdbcUrl);
registry.add("spring.datasource.username", postgres::getUsername);
registry.add("spring.datasource.password", postgres::getPassword);
}*/
}
4. Download Source Code
$ git clone https://github.com/mkyong/spring-boot.git
$ cd spring-boot-testcontainers
$ ./mvnw test -Dtest=BookRepositoryDynamicPropertyTest
5. References
- Integration tests with a dynamic property source
- SpringDoc @DynamicPropertySource
- Context Configuration with Dynamic Property Sources
- Spring Boot and Testcontainers
- Spring Test using Testcontainers
- Testcontainers Postgres Module
- Spring Boot Testcontainers example
- Spring data JPA and MySQL example
- Spring Data JPA and PostgreSQL example
- Testing Spring Data JPA with @DataJpaTest
The post Spring Boot @DynamicPropertySource Example appeared first on Mkyong.com.