Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Spring @DynamicPropertySource: bind test resources without stale cached values

Last updated: 5 Oct 20264 min read
tutorial
IntermediateBy AITrove Editorial

runtime test properties supply runtime ports and credentials, but their suppliers and shared ApplicationContext cache must follow the same resource lifecycle.

Bind the resource actually started

A database container chooses a port at runtime. A static @DynamicPropertySource method can register a supplier for the JDBC URL, user and password after the container is available. The supplier is evaluated when the property is resolved, and runtime properties take precedence over @TestPropertySource and ordinary environment values. Service connections are another Boot integration path; choose one owner for the same property to avoid confusing overrides.

Watch cache reuse

Spring caches ApplicationContexts by their test configuration shape, which includes runtime-property methods. If subclasses inherit one method but each uses a different external resource, a cached context can retain bindings from the first class. Keep the resource stable across classes that share a context, make configuration shapes distinct, or deliberately evict the context when values change. Context cache shape explains why a static method name is not a guarantee that its supplied value stayed constant.

Verify the endpoint of the connection

Log a non-secret database identity in the test, then query a marker row that exists only in the intended resource. Avoid printing passwords or full connection URLs with credentials. Stop one resource and ensure a later test does not keep using a stale pool. If several containers start in parallel, ensure each test class references its own server and cleanup does not race another class.

Implementation contract

Java
@DynamicPropertySource
static void receiptDatabase(DynamicPropertyRegistry properties) {
    properties.add("spring.datasource.url", receiptPostgres::getJdbcUrl);
    properties.add("spring.datasource.username", receiptPostgres::getUsername);
    properties.add("spring.datasource.password", receiptPostgres::getPassword);
}

Cost and verification

Supplier evaluation is cheap. Starting an external database and rebuilding contexts dominate runtime; careless cache eviction can multiply suite duration.

Common Mistakes

  • Do not register runtime properties for a resource that has not started.
  • Do not assume cached contexts refresh when an inherited supplier changes value.
  • Do not publish credentials while debugging the test database binding.

Read next

Spring Boot Testcontainers: service connections and cached-context lifecycle, Spring TestContext cache: keep equivalent tests on one context shape, Spring Testcontainers parallel tests: one database can leak another test's rows, Spring Boot file-tree tests: prove binding without claiming secret delivery, Spring Data JPA test against the deployment database dialect.

spring
spring-testing
dynamic-property-source-lifecycle
Storage details