在Spring Boot测试期间替换@Configuration中的@Value属性

时间:2016-09-08 16:31:05

标签: testing spring-boot

方案

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

不幸的是,这些测试值无法使用简单的属性文件,(String)常量或类似值覆盖,而是必须使用一些自定义编写的属性来解析Java类(例如TargetProperties.getProperty("some.username"))。

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

问题

如何在 @Value类中覆盖@Configuration带注释的字段,其中的属性是通过自定义Java代码编程获得的 em>其他任何东西都被初始化了吗?

代码

生产配置类

@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;
        }
    }
}

3 个答案:

答案 0 :(得分:11)

您可以使用setkey(v_dt, id, c) setkey(df, a, b) foverlaps(df, v_dt)[, id := NULL][,.(a, b, c)] # a b c #1: 1 35 27 #2: 45 60 NA #3: 90 110 NA #4: 115 145 NA #5: 170 190 175 #6: 203 231 230 #7: 259 270 NA 参数直接在@SpringBootTest注释中覆盖属性:

properties

答案 1 :(得分:9)

您可以使用@TestPropertySource

@TestPropertySource(
    properties = {
        "some.username=validate",
        "some.password=false"
    }
)
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class ApplicationTest {
    //...
}

答案 2 :(得分:3)

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

@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");
    }
}