26

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.

0

3 Answers 3

28

@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)

Sign up to request clarification or add additional context in comments.

3 Comments

I found this example to show how it is done in practice.
@barfuin - 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?
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/…
14

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

1 Comment

How would you do if you want to test with 2 or more values in my.property?
3

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.