Package org.springframework.test.context

# Annotation Interface ContextHierarchy

@Target(TYPE) @Retention(RUNTIME) @Documented @Inherited public @interface ContextHierarchy
`@ContextHierarchy` is an annotation that can be applied to a test class to define a hierarchy of `ApplicationContexts` for integration tests.

### Examples

The following JUnit-based examples demonstrate common configuration scenarios for integration tests that require the use of context hierarchies.

#### Single Test Class with Context Hierarchy

`ControllerIntegrationTests` represents a typical integration testing scenario for a Spring MVC web application by declaring a context hierarchy consisting of two levels, one for the root `WebApplicationContext` (with `TestAppConfig`) and one for the dispatcher servlet `WebApplicationContext` (with `WebConfig`). The `WebApplicationContext` that is autowired into the test instance is the one for the child context (i.e., the lowest context in the hierarchy).

     @ExtendWith(SpringExtension.class)
     @WebAppConfiguration
     @ContextHierarchy({
         @ContextConfiguration(classes = TestAppConfig.class),
         @ContextConfiguration(classes = WebConfig.class)
     })
     class ControllerIntegrationTests {

         @Autowired
         WebApplicationContext wac;

         // ...
     }

#### Class Hierarchy with Implicit Parent Context

The following test classes define a context hierarchy within a test class hierarchy. `AbstractWebTests` declares the configuration for a root `WebApplicationContext` in a Spring-powered web application. Note, however, that `AbstractWebTests` does not declare `@ContextHierarchy`; consequently, subclasses of `AbstractWebTests` can optionally participate in a context hierarchy or follow the standard semantics for `@ContextConfiguration`. `SoapWebServiceTests` and `RestWebServiceTests` both extend `AbstractWebTests` and define a context hierarchy via `@ContextHierarchy`. The result is that three application contexts will be loaded (one for each declaration of `@ContextConfiguration`), and the application context loaded based on the configuration in `AbstractWebTests` will be set as the parent context for each of the contexts loaded for the concrete subclasses.

     @ExtendWith(SpringExtension.class)
     @WebAppConfiguration
     @ContextConfiguration("file:src/main/webapp/WEB-INF/applicationContext.xml")
     public abstract class AbstractWebTests {}

     @ContextHierarchy(@ContextConfiguration("/spring/soap-ws-config.xml"))
     public class SoapWebServiceTests extends AbstractWebTests {}

     @ContextHierarchy(@ContextConfiguration("/spring/rest-ws-config.xml"))
     public class RestWebServiceTests extends AbstractWebTests {}

#### Class Hierarchy with Merged Context Hierarchy Configuration

The following classes demonstrate the use of named hierarchy levels in order to merge the configuration for specific levels in a context hierarchy. `BaseTests` defines two levels in the hierarchy, `"parent"` and `"child"`. `ExtendedTests` extends `BaseTests` and instructs the Spring TestContext Framework to merge the context configuration for the `"child"` hierarchy level, simply by ensuring that the names declared via `ContextConfiguration.name()` are both `"child"`. The result is that three application contexts will be loaded: one for `"/app-config.xml"`, one for `"/user-config.xml"`, and one for `{"/user-config.xml", "/order-config.xml"}`. As with the previous example, the application context loaded from `"/app-config.xml"` will be set as the parent context for the contexts loaded from `"/user-config.xml"` and `{"/user-config.xml", "/order-config.xml"}`.

     @ExtendWith(SpringExtension.class)
     @ContextHierarchy({
         @ContextConfiguration(name = "parent", locations = "/app-config.xml"),
         @ContextConfiguration(name = "child",  locations = "/user-config.xml")
     })
     public class BaseTests {}

     @ContextHierarchy(
         @ContextConfiguration(name = "child",  locations = "/order-config.xml")
     )
     public class ExtendedTests extends BaseTests {}

#### Class Hierarchy with Overridden Context Hierarchy Configuration

In contrast to the previous example, this example demonstrates how to override the configuration for a given named level in a context hierarchy by setting the `ContextConfiguration.inheritLocations()` flag to `false`. Consequently, the application context for `ExtendedTests` will be loaded only from `"/test-user-config.xml"` and will have its parent set to the context loaded from `"/app-config.xml"`.

     @ExtendWith(SpringExtension.class)
     @ContextHierarchy({
         @ContextConfiguration(name = "parent", locations = "/app-config.xml"),
         @ContextConfiguration(name = "child",  locations = "/user-config.xml")
     })
     public class BaseTests {}

     @ContextHierarchy(
         @ContextConfiguration(name = "child",  locations = "/test-user-config.xml", inheritLocations = false)
     )
     public class ExtendedTests extends BaseTests {}

#### Context Hierarchies with Bean Overrides

When `@ContextHierarchy` is used in conjunction with bean overrides such as `@TestBean`, `@MockitoBean`, or `@MockitoSpyBean`, it may be desirable or necessary to have the override applied to a single level in the context hierarchy. To achieve that, the bean override must specify a context name that matches a name configured via `ContextConfiguration.name()`.

The following test class configures the name of the second hierarchy level to be `"user-config"` and simultaneously specifies that the `UserService` should be wrapped in a Mockito spy in the context named `"user-config"`. Consequently, Spring will only attempt to create the spy in the `"user-config"` context and will not attempt to create the spy in the parent context.

     @ExtendWith(SpringExtension.class)
     @ContextHierarchy({
         @ContextConfiguration(classes = AppConfig.class),
         @ContextConfiguration(classes = UserConfig.class, name = "user-config")
     })
     class IntegrationTests {

         @MockitoSpyBean(contextName = "user-config")
         UserService userService;

         // ...
     }

When applying bean overrides in different levels of the context hierarchy, you may need to have all of the bean override instances injected into the test class in order to interact with them — for example, to configure stubbing for mocks. However, `@Autowired` will always inject a matching bean found in the lowest level of the context hierarchy. Thus, to inject bean override instances from specific levels in the context hierarchy, you need to annotate fields with appropriate bean override annotations and configure the name of the context level.

The following test class configures the names of the hierarchy levels to be `"parent"` and `"child"`. It also declares two `PropertyService` fields that are configured to create or replace `PropertyService` beans with Mockito mocks in the respective contexts, named `"parent"` and `"child"`. Consequently, the mock from the `"parent"` context will be injected into the `propertyServiceInParent` field, and the mock from the `"child"` context will be injected into the `propertyServiceInChild` field.

     @ExtendWith(SpringExtension.class)
     @ContextHierarchy({
         @ContextConfiguration(classes = ParentConfig.class, name = "parent"),
         @ContextConfiguration(classes = ChildConfig.class, name = "child")
     })
     class IntegrationTests {

         @MockitoBean(contextName = "parent")
         PropertyService propertyServiceInParent;

         @MockitoBean(contextName = "child")
         PropertyService propertyServiceInChild;

         // ...
     }

#### Miscellaneous

This annotation may be used as a meta-annotation to create custom composed annotations.

This annotation will be inherited from an enclosing test class by default. See `@NestedTestConfiguration` for details.

Since:
  3.2.2
Author:
  Sam Brannen
See Also:
  - `ContextConfiguration`
  - `ApplicationContext`

## Required Element Summary

Required Elements
Modifier and Type
Required Element
Description
`ContextConfiguration[]`
`value`
A list of `@ContextConfiguration` instances, each of which defines a level in the context hierarchy.

## Element Details

### value

ContextConfiguration[] value
A list of `@ContextConfiguration` instances, each of which defines a level in the context hierarchy.

If you need to merge or override the configuration for a given level of the context hierarchy within a test class hierarchy, you must explicitly name that level by supplying the same value to the `name` attribute in `@ContextConfiguration` at each level in the class hierarchy. See the class-level Javadoc for examples.