如何使用 spring-boot-test 中的 ApplicationContextRunner 测试 @ConfigurationProperties?
How to test @ConfigurationProperties with ApplicationContextRunner from spring-boot-test?
我需要测试使用 @ConfigurationProperties bean 的自动配置 类。我正在使用 https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-test-autoconfig 中记录的 ApplicationContextRunner 来加快测试速度并避免在每个变体之间启动 servlet 容器。但是,使用 @AutoconfigurationProperties 注释的 bean 不会填充注入到 ApplicationContextRunner 中的值。
我怀疑我遇到了类似于
的问题
@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.
如何使用 ApplicationContextRunner 启用对@ConfigurationProperties 的支持?
这里是对应的代码
@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");
});
}
失败:
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();
}
[...]
}
提供完整资源
ps:我正要向 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 提交问题,我首先要确保我没有误解问题。
据我所知,您的测试中涉及的 类 中的 none 启用了配置 属性 绑定。因此,没有属性绑定到 ServiceDefinitionMapperProperties
。您可以使用 @EnableConfigurationProperties
启用配置 属性 绑定。添加它的典型位置是 DynamicCatalogServiceAutoConfiguration
,因为它的 serviceDefinitionMapperProperties
bean 依赖于启用的配置属性。
如果你想填充一个用 @ConfigurationProperties
class 注释的 bean 作为你测试的一部分,你通常依赖一个配置 class 用 @EnableConfigurationProperties
注释来填充那个 bean,然后你可以创建一个简单的配置 class 只是为了测试:
@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());
});
}
}
将 TrivialConfiguration
传递给 ApplicationContextRunner
足以使其创建 ConfigProps
并使用可用属性填充它。
我需要测试使用 @ConfigurationProperties bean 的自动配置 类。我正在使用 https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-test-autoconfig 中记录的 ApplicationContextRunner 来加快测试速度并避免在每个变体之间启动 servlet 容器。但是,使用 @AutoconfigurationProperties 注释的 bean 不会填充注入到 ApplicationContextRunner 中的值。
我怀疑我遇到了类似于
的问题@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.
如何使用 ApplicationContextRunner 启用对@ConfigurationProperties 的支持?
这里是对应的代码
@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");
});
}
失败:
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();
}
[...]
}
提供完整资源
ps:我正要向 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 提交问题,我首先要确保我没有误解问题。
据我所知,您的测试中涉及的 类 中的 none 启用了配置 属性 绑定。因此,没有属性绑定到 ServiceDefinitionMapperProperties
。您可以使用 @EnableConfigurationProperties
启用配置 属性 绑定。添加它的典型位置是 DynamicCatalogServiceAutoConfiguration
,因为它的 serviceDefinitionMapperProperties
bean 依赖于启用的配置属性。
如果你想填充一个用 @ConfigurationProperties
class 注释的 bean 作为你测试的一部分,你通常依赖一个配置 class 用 @EnableConfigurationProperties
注释来填充那个 bean,然后你可以创建一个简单的配置 class 只是为了测试:
@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());
});
}
}
将 TrivialConfiguration
传递给 ApplicationContextRunner
足以使其创建 ConfigProps
并使用可用属性填充它。