在 Spring Boot 测试期间替换 @Configuration 中的 @Value 属性 [英] Replace @Value property within @Configuration during Spring Boot test

查看:70
本文介绍了在 Spring Boot 测试期间替换 @Configuration 中的 @Value 属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有 @Configuration 注释的 Spring 配置类的 Spring Boot 应用程序,其中包含一些 @Value 注释字段.为了测试,我想用自定义测试值替换这些字段值.

I've got a Spring Boot application with a @Configuration annotated Spring configuration class which contains some @Value annotated fields. For testing I want to replace these field values with custom test values.

不幸的是,这些测试值不能使用简单的属性文件、(字符串)常量或类似文件覆盖,相反我必须使用一些自定义编写的属性解析 Java 类(例如 TargetProperties.getProperty("some.username")).

Unfortunately these test values cannot be overridden using a simple properties file, (String) constants or similar, instead I must use some custom written property resolving Java class (e.g. TargetProperties.getProperty("some.username")).

我遇到的问题是,当我在测试配置中向 ConfigurableEnvironment 添加自定义 PropertySource 时,已经太晚了,因为这个 PropertySource 将添加之后例如RestTemplate 已创建.

The problem I have is that when I add a custom PropertySource to the ConfigurableEnvironment within my test configuration, it's already too late because this PropertySource will be added after the e.g. RestTemplate has been created.

如何覆盖@Value 注释字段 一个@Configuration 类,其属性以编程方式通过自定义获得Java 代码其他任何东西被初始化之前?

How can I override @Value annotated fields within a @Configuration class with properties obtained programmatically via custom Java code before anything else gets initialized?

@Configuration
public class SomeConfiguration {

    @Value("${some.username}")
    private String someUsername;

    @Value("${some.password}")
    private String somePassword;

    @Bean
    public RestTemplate someRestTemplate() {
        RestTemplate restTemplate = new RestTemplate();

        restTemplate.getInterceptors().add(
            new BasicAuthorizationInterceptor(someUsername, somePassword));

        return restTemplate;
    }

}

测试配置类

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class SomeTest {

    @SpringBootConfiguration
    @Import({MySpringBootApp.class, SomeConfiguration.class})
    static class TestConfiguration {

        @Autowired
        private ConfigurableEnvironment configurableEnvironment;

        // This doesn't work:

        @Bean
        @Lazy(false)
        // I also tried a @PostConstruct method
        public TargetPropertiesPropertySource targetPropertiesPropertySource() {
            TargetPropertiesPropertySource customPropertySource =
                new TargetPropertiesPropertySource();
            configurableEnvironment.getPropertySources().addFirst(customPropertySource);
            return customPropertySource;
        }
    }
}

推荐答案

您可以在生产案例中使用构造函数注入,这允许它手动设置配置:

You can use constructor injection in production cases, which allows it to set the configuration manually:

@Configuration
public class SomeConfiguration {

    private final String someUsername;
    private final String somePassword;

    @Autowired
    public SomeConfiguration(@Value("${some.username}") String someUsername,
       @Value("${some.password}") String somePassword) {
       this.someUsername = someUsername;
       this.somePassword = somePassword;
    }
...
)
}

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class SomeTest {

    private SomeConfiguration config;

    @Before
    public init() {
      config = new SomeConfiguration("foo", "bar");
    }
}

这篇关于在 Spring Boot 测试期间替换 @Configuration 中的 @Value 属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆