Spring ConfigurationProperties初始化机制及测试加载失败排查咨询
Let’s start by breaking down how Spring handles @ConfigurationProperties beans—this will help you pinpoint why your test setup isn’t loading the config values correctly:
How @ConfigurationProperties Works in Spring
Here’s the step-by-step flow for your CityProperties class:
- Bean Registration: Since you’ve annotated it with
@Component, Spring scans for this class during context startup and registers it as a bean. The@ConfigurationProperties(prefix = "city")tells Spring which properties to map to this bean. - Property Binding: Spring pulls matching properties from your environment (like
application.properties) using the prefix + field name. It uses "relaxed binding" too—sopopulationAmountWorkshopwill matchcity.population-amount-workshoporcity.population_amount_workshopif you used those formats. - Nested Classes: For nested static classes such as
LoanerorTax, Spring extends the binding path:city.loaner.maxRequestmaps directly toCityProperties.Loaner.maxRequest. - Default Values: If no matching property is found, Spring falls back to the default values you initialized (like
new Loaner()) or the type’s default (0 for int, 0.0 for double)—which is exactly what you’re seeing in tests.
Troubleshooting Your SavegameTestApplication Setup
Since production works but tests don’t, these are the most common culprits to check:
1. Missing @EnableConfigurationProperties in Test Context
Even with @Component, test contexts sometimes skip auto-processing configuration properties. Explicitly enable it for your CityProperties class in your test or test configuration:
@SpringBootTest(classes = SavegameTestApplication.class) @EnableConfigurationProperties(CityProperties.class) public class YourTestClass { @Autowired private CityProperties cityProperties; // Your test logic here }
2. Test Isn’t Loading the Correct application.properties
By default, Spring Boot tests look for config files in src/test/resources. If your test has its own application.properties without the city.* entries, or if it’s not picking up the main config file, you’ll get default values:
- Verify the
city.*properties exist in your test’sapplication.properties, or configure the test to load the main config file explicitly. - If you use profiles, make sure the test activates the profile that includes the city properties.
3. Component Scan Doesn’t Include CityProperties
Spring’s @SpringBootApplication scans packages below the application class by default. If CityProperties is in a package outside this scope, add a component scan to your test application:
@SpringBootApplication @ComponentScan(basePackages = {"com.your.main.package", "com.your.package.with.cityproperties"}) public class SavegameTestApplication { // ... }
4. Test is Overriding the CityProperties Bean
Check if your test (or any parent test config) uses @MockBean or a test-specific bean definition that replaces the real CityProperties with a mock or default instance. If so, remove that override or adjust it to load the actual config.
5. Debug the Binding Process
Enable debug logging for Spring’s property binding to see exactly what’s happening. Add this to your test’s application.properties:
logging.level.org.springframework.boot.context.properties=DEBUG
When you run the test, look for logs about binding CityProperties—you’ll see which properties are being loaded, or why Spring is falling back to defaults.
内容的提问来源于stack exchange,提问作者hotzst

