Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace @Value property within @Configuration during Spring Boot test

Scenario

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.

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")).

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.

Question

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

Code

Production Configuration Class

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

}

Test Configuration Class

@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;
        }
    }
}
like image 613
Markus Ratzer Avatar asked Sep 08 '16 16:09

Markus Ratzer


2 Answers

You can override properties directly in the @SpringBootTest annotation using the properties parameter:

@SpringBootTest(properties = {"some.username=user", "some.password=pwd"},
                webEnvironment = SpringBootTest.WebEnvironment.NONE)
like image 195
alexbt Avatar answered Jan 01 '23 02:01

alexbt


You can use @TestPropertySource

@TestPropertySource(
    properties = {
        "some.username=validate",
        "some.password=false"
    }
)
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class ApplicationTest {
    //...
}
like image 22
A0__oN Avatar answered Jan 01 '23 04:01

A0__oN