Close

Spring Core Testing - @TestBean with Context Hierarchy

[Last Updated: Feb 12, 2026]

Spring allows tests to be executed with hierarchical application contexts, typically consisting of parent and child contexts. In such cases, bean overriding must be scoped carefully to avoid unintended side effects.

@TestBean (check tutorial here) provides the contextName attribute to target a specific context in the hierarchy. This allows precise control over where a bean replacement should occur.

Why contextName is important

Without contextName, Spring applies the override to the most specific matching context. In complex setups, this can lead to ambiguity or incorrect overrides. Explicit context naming removes that risk.

Example

Spring App

package com.logicbig.example;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ParentConfig {

    @Bean
    public Database database() {
        return new Database("jdbc:h2:mem:testdb");
    }
}
package com.logicbig.example;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ChildConfig {

    @Bean
    public UserService userService(Database dbConfig) {
        return new UserService(dbConfig);
    }
}
package com.logicbig.example;

public class Database {
    private final String connectionUrl;

    public Database(String connectionUrl) {
        this.connectionUrl = connectionUrl;
    }

    public String getConnectionUrl() {
        return connectionUrl;
    }
}
package com.logicbig.example;

public class UserService {
    private final Database dbConfig;

    public UserService(Database dbConfig) {
        this.dbConfig = dbConfig;
    }

    public String getUser(String username) {
        return "User: " + username + " from " + dbConfig.getConnectionUrl();
    }
}

Integration Test

This test defines a parent and child context. The test bean override is applied only to the child context using contextName.

package com.logicbig.example;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.ContextHierarchy;
import org.springframework.test.context.bean.override.convention.TestBean;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.junit.jupiter.api.Assertions.assertTrue;

@ExtendWith(SpringExtension.class)
@ContextHierarchy({
        @ContextConfiguration(classes = ParentConfig.class),
        @ContextConfiguration(classes = ChildConfig.class)
})
public class ContextHierarchyTestBeanTest {

    @Autowired
    private UserService userService;

    @TestBean(name = "database")
    Database database;

    static Database database() {
        return new Database("jdbc:h2:mem:testdb-override");
    }

    @Test
    public void testHierarchyWithTestBean() {
        String result = userService.getUser("john");
        System.out.println("Result: " + result);

        assertTrue(result.contains("testdb-override"));

      ;
    }
}

Output

$ mvn test
[INFO] Scanning for projects...
[INFO]
[INFO] ----------< com.logicbig.example:test-bean-context-hierarchy >----------
[INFO] Building test-bean-context-hierarchy 1.0-SNAPSHOT
[INFO] from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- resources:3.3.1:resources (default-resources) @ test-bean-context-hierarchy ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory D:\example-projects\spring-core-testing\test-bean-context-hierarchy\src\main\resources
[INFO]
[INFO] --- compiler:3.11.0:compile (default-compile) @ test-bean-context-hierarchy ---
[INFO] Changes detected - recompiling the module! :input tree
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 4 source files with javac [debug target 21] to target\classes
[INFO]
[INFO] --- resources:3.3.1:testResources (default-testResources) @ test-bean-context-hierarchy ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory D:\example-projects\spring-core-testing\test-bean-context-hierarchy\src\test\resources
[INFO]
[INFO] --- compiler:3.11.0:testCompile (default-testCompile) @ test-bean-context-hierarchy ---
[INFO] Changes detected - recompiling the module! :dependency
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 1 source file with javac [debug target 21] to target\test-classes
[INFO]
[INFO] --- surefire:3.2.5:test (default-test) @ test-bean-context-hierarchy ---
[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider
[WARNING] file.encoding cannot be set as system property, use <argLine>-Dfile.encoding=...</argLine> instead
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.logicbig.example.ContextHierarchyTestBeanTest
Result: User: john from jdbc:h2:mem:testdb-override
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.905 s -- in com.logicbig.example.ContextHierarchyTestBeanTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8.726 s
[INFO] Finished at: 2026-02-09T19:40:03+08:00
[INFO] ------------------------------------------------------------------------

Conclusion

The output verifies that the overridden bean is visible only within the targeted child context. This confirms that @TestBean respects context boundaries and allows fine-grained bean replacement in hierarchical test configurations.

Example Project

Dependencies and Technologies Used:

  • spring-context 7.0.4 (Spring Context)
     Version Compatibility: 6.2.0 - 7.0.4Version List
    ×

    Version compatibilities of spring-context with this example:

    • 6.2.0
    • 6.2.1
    • 6.2.2
    • 6.2.3
    • 6.2.4
    • 6.2.5
    • 6.2.6
    • 6.2.7
    • 6.2.8
    • 6.2.9
    • 6.2.10
    • 6.2.11
    • 6.2.12
    • 6.2.13
    • 6.2.14
    • 6.2.15
    • 6.2.16
    • 7.0.0
    • 7.0.1
    • 7.0.2
    • 7.0.3
    • 7.0.4

    Versions in green have been tested.

  • spring-test 7.0.4 (Spring TestContext Framework)
  • junit-jupiter-engine 6.0.2 (Module "junit-jupiter-engine" of JUnit)
  • JDK 25
  • Maven 3.9.11

Spring Core Testing - TestBean with context hierarchy Select All Download
  • test-bean-context-hierarchy
    • src
      • main
        • java
          • com
            • logicbig
              • example
      • test
        • java
          • com
            • logicbig
              • example
                • ContextHierarchyTestBeanTest.java

    See Also

    Join