@TestPropertySource with dynamic properties
Asked Answered
E

3

22

I am using @TestPropertySource to overwrite application.yml properties in my integration test for a spring boot app.

@TestPropertySource(properties = { "repository.file.path=src/test/resources/x" })

I was wondering if there was some way to make the property VALUE dynamic. Something like this:

 @TestPropertySource(properties = { "repository.file.path=PropertyValueProvider.class" })

Your feedback is appreciated. In my case the property value is system specific that should be generated upon the test run.

Enallage answered 22/11, 2015 at 14:26 Comment(0)
G
27

@TestPropertySource only provides declarative mechanisms for configuring PropertySources. Documentation in Spring Reference Manual.

If you need programmatic support for adding a PropertySource to the Environment, you should implement an ApplicationContextInitializer which can be registered via @ContextConfiguration(initializers = ...). Documentation in Spring Reference Manual.

Regards,

Sam (author of the Spring TestContext Framework)

Gourley answered 24/6, 2016 at 12:20 Comment(3)
I found this example to show how it is done in practice.Jemadar
@Jemadar - This looks like exactly what i need...except I'm using Boot v1.5 and that example uses features (TestPropertyValues) introduced in 2.0. Don't suppose anyone would have any other examples?Dnepropetrovsk
In Spring Boot 1.5.x you can use the properties attribute of @SpringBootTest: docs.spring.io/spring-boot/docs/1.5.21.BUILD-SNAPSHOT/api/org/…Gourley
N
11

You can also do this with the @DynamicPropertySource annotation in Spring Boot 5.2. This enables you to set the property value programmatically (dynamically).

See: https://github.com/spring-projects/spring-framework/issues/24540

Add this to your integration test class:

@DynamicPropertySource
static void dynamicProperties(DynamicPropertyRegistry registry) {
  registry.add("my.property", () -> {
       // some logic to get your property dynamically
   });
}
Newfeld answered 7/1, 2022 at 22:49 Comment(1)
How would you do if you want to test with 2 or more values in my.property?Phene
F
1

I did this thanks to Sam Brannen's answer

Here's the sample code:

@ContextConfiguration(classes = { MyConfiguration.class }, initializers = { MyInitializer.class })
public class MyContextConfiguration {
    public static class MyInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
        @Override
        public void initialize(ConfigurableApplicationContext applicationContext) {
            String userNameLower = System.getProperty("user.name").toLowerCase();
            Map<String, Object> dynamicProperties = Map.of("user.name.lower", userNameLower);
            MapPropertySource propertySource = new MapPropertySource("dynamic", dynamicProperties);
            applicationContext.getEnvironment().getPropertySources().addLast(propertySource);
        }
    }

    @Configuration
    @PropertySource("classpath:my-static.properties") // properties in this file can reference ${user.name.lower}
    public static class MyConfiguration {
        @Bean
        public MyBean myBean(@Value("${user.name.lower}") String userNameLower) {
            return new MyBean(userNameLower);
        }
    }
}
Frolic answered 5/11, 2021 at 8:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.