How do you use test-specific configuration (@TestPropertySource, application-test.yml, test profiles)?

7 minintermediatetestpropertysourcetest-profilesconfiguration

Quick Answer

Test-specific configuration lets you override properties (a test database URL, a disabled external integration, a faster-but-less-secure encoder) only for the test run, without touching the application's real configuration files. Common approaches: an application-test.yml/properties file activated via a dedicated 'test' Spring profile (@ActiveProfiles("test")), or @TestPropertySource to set/override specific properties directly on a test class, both of which layer on top of (and can override) the application's normal configuration precedence.

Detailed Answer

Tests frequently need different configuration than the real application — a test-only database URL, a disabled or stubbed-out external integration, relaxed security settings for convenience, or faster (if less secure) settings that would be inappropriate in production but are fine for a test run.

1. A dedicated test profile, with its own properties file:

src/test/resources/application-test.yml
spring:
  datasource:
    url: jdbc:h2:mem:testdb
logging:
  level:
    org.springframework: WARN

Activated on the test class:

@SpringBootTest
@ActiveProfiles("test") // loads application-test.yml on top of the base application.yml
class OrderServiceIntegrationTest { ... }

2. @TestPropertySource — set or override specific properties directly on the test class, without a separate profile-specific file:

@SpringBootTest
@TestPropertySource(properties = {
    "app.feature.new-checkout-flow.enabled=false",
    "spring.datasource.url=jdbc:h2:mem:testdb"
})
class CheckoutServiceTest { ... }

Can also point at a specific properties file: @TestPropertySource(locations = "classpath:test-specific.properties").

Both approaches layer on top of Spring Boot's normal configuration precedence — a test-specific property (whether from a profile-specific file or @TestPropertySource) overrides the base application.yml's value for that property, exactly as an active-profile file would in a non-test context, letting the same overall configuration-resolution model apply consistently to both production and test scenarios.

Practical guidance on choosing between them:

  • Use a dedicated application-test.yml + @ActiveProfiles("test") for a broader, reusable set of test-environment defaults shared across many test classes (e.g., "tests always use an in-memory database and disabled external calls").
  • Use @TestPropertySource for a small number of property overrides specific to one particular test class's needs, where creating an entire separate profile file would be overkill.

Both are commonly combined with @DynamicPropertySource (seen in the Testcontainers example) when a property's value isn't known statically ahead of time — e.g., a Testcontainers-assigned random port — since @TestPropertySource/profile files can only hold static values known at compile/config time.