I need to test my autoconfiguration classes that make use of @ConfigurationProperties beans. I'm making use of ApplicationContextRunner as documented in https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-test-autoconfig to make tests faster and avoid starting the servlet container between each variations. However, beans annotated with @AutoconfigurationProperties are not populated with values injected into ApplicationContextRunner.
I suspect that I'm hitting problem similar to https://stackoverflow.com/a/56023100/1484823
@ConfigurationProperties are not managed by the application context you build in tests, although they will be load when the application launches, because you have @EnableConfigurationProperties on your app main class.
How can I enable support for @ConfigurationProperties with ApplicationContextRunner ?
Here is the corresponding code
@Test
void ServiceDefinitionMapperPropertiesAreProperlyLoaded() {
ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(
SingleServiceDefinitionAnswerAutoConfig.class,
DynamicCatalogServiceAutoConfiguration.class
))
// .withPropertyValues(DynamicCatalogProperties.OPT_IN_PROPERTY + "=true") //Not sure why this seems ignored
.withSystemProperties(DynamicCatalogConstants.OPT_IN_PROPERTY + "=true",
ServiceDefinitionMapperProperties.PROPERTY_PREFIX
+ServiceDefinitionMapperProperties.SUFFIX_PROPERTY_KEY+ "=suffix")
;
contextRunner.run(context -> {
assertThat(context).hasSingleBean(ServiceDefinitionMapperProperties.class);
ServiceDefinitionMapperProperties serviceDefinitionMapperProperties
= context.getBean(ServiceDefinitionMapperProperties.class);
assertThat(serviceDefinitionMapperProperties.getSuffix()).isEqualTo("suffix");
});
}
which fails with:
org.opentest4j.AssertionFailedError:
Expecting:
<"">
to be equal to:
<"suffix">
but was not.
Expected :suffix
Actual :
<Click to see difference>
at org.springframework.cloud.appbroker.autoconfigure.DynamicCatalogServiceAutoConfigurationTest
public class DynamicCatalogServiceAutoConfiguration {
[...]
@Bean
@ConfigurationProperties(prefix=ServiceDefinitionMapperProperties.PROPERTY_PREFIX, ignoreUnknownFields = false)
public ServiceDefinitionMapperProperties serviceDefinitionMapperProperties() {
return new ServiceDefinitionMapperProperties();
}
[...]
}
Full sources available at https://github.com/orange-cloudfoundry/osb-cmdb-spike/blob/0da641e5f2f811f48b0676a25c8cbe97895168d1/spring-cloud-app-broker-autoconfigure/src/test/java/org/springframework/cloud/appbroker/autoconfigure/DynamicCatalogServiceAutoConfigurationTest.java#L89-L107
ps: I was about to submit an issue to https://github.com/spring-projects/spring-boot/issues to suggest documentation enhancement to warn of such limitation in ApplicationContext, and to ask for ways to turn on support for @ConfigurationProperties. Following guidance at https://raw.githubusercontent.com/spring-projects/spring-boot/master/.github/ISSUE_TEMPLATE.md, I'm first making sure here I'm not misunderstanding the problem.
If you want to populate a bean annotated with @ConfigurationProperties
class as part of your test, and you normally depend on a configuration class annotated with @EnableConfigurationProperties
to populate that bean, then you can create a trivial configuration class just for the test:
@ConfigurationProperties("app")
public class ConfigProps {
private int meaningOfLife;
public int getMeaningOfLife() { return meaningOfLife; }
public void setMeaningOfLife(int meaning) { this.meaningOfLife = meaning; }
}
class ConfigPropsTest {
private final ApplicationContextRunner runner = new ApplicationContextRunner();
@EnableConfigurationProperties(ConfigProps.class)
static class TrivialConfiguration {
}
@Test
void test() {
runner.withUserConfiguration(TrivialConfiguration.class)
.withPropertyValues("app.meaning-of-life=42")
.run(context -> {
assertEquals(42, context.getBean(ConfigProps.class).getMeaningOfLife());
});
}
}
Passing TrivialConfiguration
to the ApplicationContextRunner
is sufficient to make it create ConfigProps
and populate it using the available properties.
As far as I can tell, none of the classes involved in your test enable configuration property binding. As a result, no properties are bound to ServiceDefinitionMapperProperties
. You can enable configuration property binding using @EnableConfigurationProperties
. A typical place to add it would be on DynamicCatalogServiceAutoConfiguration
as its serviceDefinitionMapperProperties
bean relies on configuration properties being enabled.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With