skip to content

@ActiveProfiles & @TestPropertySource

@ActiveProfiles and @TestPropertySource let a test pick a profile and override properties, taking precedence over the application's own files. Interviewers ask because these values are part of the context cache key.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

questions

5

What does @ActiveProfiles do in a Spring integration test, and how do you use it?

level: juniorimportance: must knowfreq 70%

answer

  1. Class-level, activates @Profile beans
  2. Test equivalent of spring.profiles.active
  3. Loads application-{profile}.properties in Boot
  4. Part of context cache key
  5. inheritProfiles default true

basics

~10 s

@ActiveProfiles activates one or more Spring bean-definition profiles for a test's ApplicationContext. You put it on the test class, e.g. @ActiveProfiles("test"), so beans and property files tied to that profile are loaded.

solid answer

~40 s

@ActiveProfiles is a class-level test annotation that tells the Spring TestContext Framework which bean-definition profiles to activate when it builds the ApplicationContext for that test. It's the test-time equivalent of setting spring.profiles.active at runtime. You declare it as @ActiveProfiles("test") or @ActiveProfiles({"test","integration"}). Any @Configuration/@Bean guarded by @Profile("test"), and profile-specific property files like application-test.properties (with Boot), then take effect. It's commonly used to swap in test doubles (e.g. an in-memory or mock external client) or point at a test datasource. Because the set of active profiles is part of the context cache key, tests with different @ActiveProfiles values get separate cached contexts rather than sharing one.

code

kotlin · 21 lines
kotlin
@SpringBootTest
@ActiveProfiles("test")
class OrderServiceTest {

    @Autowired
    lateinit var mailSender: MailSender // resolves to the @Profile("test") stub

    @Test
    fun `uses the test mail stub`() {
        assertThat(mailSender).isInstanceOf(NoOpMailSender::class.java)
    }
}

@Configuration
class MailConfig {
    @Bean @Profile("test")
    fun stubMail(): MailSender = NoOpMailSender()

    @Bean @Profile("!test")
    fun realMail(): MailSender = SmtpMailSender()
}

go deeper

for a junior

Know it's class-level and activates @Profile beans / loads application-{profile}.properties.

for a middle

Know multiple profiles, inheritProfiles, and the difference from @TestPropertySource.

for a senior

Explain context-cache-key impact and how profile-specific property files layer in Boot.

for a principal

Reason about suite-wide context proliferation and ActiveProfilesResolver for computed environments.

## What a profile is A **bean-definition profile** is a named group of beans in Spring. You mark a `@Configuration` class or an individual `@Bean` method (or a `@Component`) with `@Profile("someName")`, and those beans only enter the `ApplicationContext` when that profile is **active**. Profiles let one codebase carry alternative wirings — e.g. a real email sender in prod and a no-op stub in tests. ## What @ActiveProfiles does `@ActiveProfiles` (package `org.springframework.test.context`) is an annotation from the **Spring TestContext Framework** (the machinery behind `@SpringBootTest`, `@DataJpaTest`, `@WebMvcTest`, etc.). Placed on a **test class**, it declares which profiles should be active while that test's context is built. It is the test-time equivalent of the `spring.profiles.active` property you'd set at runtime. ```java @SpringBootTest @ActiveProfiles("test") class OrderServiceTest { } ``` With the `test` profile active: - Beans annotated `@Profile("test")` are created; beans annotated `@Profile("!test")` (or another profile) are skipped. - In Spring **Boot**, the profile-specific file `application-test.properties` / `application-test.yml` is loaded **on top of** the default `application.properties`. ## Syntax variants - Single: `@ActiveProfiles("test")`. - Multiple: `@ActiveProfiles({"test", "integration"})` or `@ActiveProfiles(profiles = {"test", "integration"})` — multiple profiles can be active at once. - **Inheritance**: by default a subclass **inherits** the superclass's active profiles. Set `inheritProfiles = false` to replace rather than merge. There's also a `resolver` attribute (`ActiveProfilesResolver`) for computing profiles programmatically. ## Context caching interaction (key gotcha) The TestContext Framework **caches** the `ApplicationContext` across test classes to save startup cost. The cache key includes the set of active profiles (order-independent — `{"a","b"}` equals `{"b","a"}`). So two test classes with the same config but **different** `@ActiveProfiles` get **separate** contexts, while identical ones **share** a cached context. Proliferating distinct profile combinations silently multiplies contexts and slows the suite. ## Common uses - Swapping infrastructure beans (mock/fake external clients, embedded datasource). - Selecting a test-specific property file in Boot. - Turning features on/off via `@Profile`-guarded config. ## Gotchas - If **no** `@Profile` beans and **no** profile-specific property file exist, adding `@ActiveProfiles` does nothing visible — it only matters when something keys off the profile. - `@ActiveProfiles` activates profiles; it does **not** by itself inject arbitrary properties — use `@TestPropertySource` for that. - The `default` profile only applies when **no** profile is active; activating any profile disables `default`-only beans.

  • Can a test have more than one active profile?
    Yes — @ActiveProfiles({"test","integration"}). All listed profiles are active simultaneously, so beans guarded by either profile are created.
  • How does @ActiveProfiles affect context caching?
    The active-profile set is part of the context cache key (order-independent). Different profile sets yield separate cached contexts; identical sets share one, so avoid needless combinations.

saying these in an interview costs you the question

  • Thinking @ActiveProfiles injects property values (it activates profiles, not properties)
  • Believing the default profile stays active after another profile is activated
  • Assuming subclasses ignore the parent's profiles (they inherit by default)

context

open as a page

In @TestPropertySource, what's the difference between the properties/value attributes and the locations attribute, and which wins when both are used?

level: middleimportance: must knowfreq 60%

basics

~20 s

locations points to property files (e.g. "classpath:test.properties"); properties (or value) lists inlined key=value pairs directly in the annotation. When a key appears in both, the inlined properties win — they're applied last with higher precedence.

open as a page

How do @ActiveProfiles and @TestPropertySource work together, and when would you choose one over the other?

level: middleimportance: should knowfreq 40%

basics

~20 s

They solve different problems: @ActiveProfiles picks WHICH beans/config files are active; @TestPropertySource sets WHAT property values apply. Use profiles to swap wiring (mock vs real beans, a profile file); use @TestPropertySource to override individual property values. They combine freely.

open as a page

Where does a @TestPropertySource source sit in the Environment's property-source ordering, and does it override application.properties and OS environment variables?

level: seniorimportance: should knowfreq 45%

basics

~20 s

Spring inserts the @TestPropertySource properties as the highest-precedence source among the application's own property sources, so it overrides application.properties. It does not, however, override actual JVM system properties or OS environment variables, which Spring still ranks higher.

open as a page

How do @ActiveProfiles and @TestPropertySource affect the TestContext context cache, and why can careless use slow a large test suite?

level: principalimportance: should knowfreq 30%

basics

~20 s

The set of active profiles and the test property sources are both part of the key the TestContext Framework uses to cache ApplicationContexts. Any difference produces a distinct key, so a new context is built instead of reusing a cached one — many unique combinations mean many expensive context startups.

open as a page