skip to content

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