By default, if you use the @ContextConfiguration annotation without specifying the classes attribute, the Spring TestContext framework attempts to automatically detect configuration. It specifically looks for static nested classes within the test class that are annotated with @Configuration.
This follows the 'Convention over Configuration' principle, allowing for more concise test code when a test requires a specific, self-contained setup. According to the AnnotationConfigContextLoader documentation, the name of the nested class does not matter, and you can even define multiple nested configuration classes to contribute to the same context.
Example
In this example, we define a test class with two static nested configuration classes. Notice that @ContextConfiguration has no attributes, yet the beans defined in the inner classes are successfully wired into the test.
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.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.junit.jupiter.api.Assertions.assertEquals;
@ExtendWith(SpringExtension.class)
@ContextConfiguration
public class ImplicitConfigTest {
@Autowired
private String message;
@Autowired
private Integer code;
@Configuration
static class LocalConfig {
@Bean
public String message() {
return "Implicit Config";
}
}
@Configuration
static class AdditionalConfig {
@Bean
public Integer code() {
return 200;
}
}
@Test
void testImplicitDetection() {
System.out.println("Testing implicit config");
assertEquals("Implicit Config", message);
assertEquals(Integer.valueOf(200), code);
}
}
Output$ mvn test [INFO] Scanning for projects... [INFO] [INFO] --------< com.logicbig.example:implicit-configuration-classes >--------- [INFO] Building implicit-configuration-classes 1.0-SNAPSHOT [INFO] from pom.xml [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- resources:3.3.1:resources (default-resources) @ implicit-configuration-classes --- [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\implicit-configuration-classes\src\main\resources [INFO] [INFO] --- compiler:3.11.0:compile (default-compile) @ implicit-configuration-classes --- [INFO] No sources to compile [INFO] [INFO] --- resources:3.3.1:testResources (default-testResources) @ implicit-configuration-classes --- [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\implicit-configuration-classes\src\test\resources [INFO] [INFO] --- compiler:3.11.0:testCompile (default-testCompile) @ implicit-configuration-classes --- [INFO] Changes detected - recompiling the module! :source [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 25] to target\test-classes [INFO] [INFO] --- surefire:3.2.5:test (default-test) @ implicit-configuration-classes --- [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.ImplicitConfigTest Testing implicit config [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.305 s -- in com.logicbig.example.ImplicitConfigTest [INFO] [INFO] Results: [INFO] [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 2.269 s [INFO] Finished at: 2026-02-04T08:50:38+08:00 [INFO] ------------------------------------------------------------------------
Conclusion
The output of this test confirms that Spring successfully scanned and loaded both LocalConfig and AdditionalConfig. This feature is highly effective for creating self-contained, isolated tests that don't need to reference external configuration files or large production @Configuration classes, keeping the test logic and its dependencies in a single, readable file.
Example ProjectDependencies and Technologies Used: - spring-context 7.0.3 (Spring Context)
Version Compatibility: 5.1.0.RELEASE - 7.0.3 Version compatibilities of spring-context with this example: Versions in green have been tested.
- spring-test 7.0.3 (Spring TestContext Framework)
- junit-jupiter-engine 6.0.2 (Module "junit-jupiter-engine" of JUnit)
- JDK 25
- Maven 3.9.11
|