Reputation: 4658
The situation I'm in requires a file with some properties (eventually containing a list of ID's and Email addresses) to be mapped to a HashMap. In Spring I found that a properties file can be mapped to an object with @ConfigurationProperties
and @PropertySource
. To test this mechanism, I created a test project, but @PropertySource
seems to be ignored when default application.properties
file exists. I'm wondering how this is possible and how I can solve it so that it uses the properties file specified.
Application.java
@SpringBootApplication
@EnableConfigurationProperties
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
DemoProperties.java
@Component
@Configuration
@ConfigurationProperties("test")
@PropertySource("classpath:test.properties")
public class DemoProperties {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
test.properties
test.name=myNameGood
application.properties
test.name=myNameBad
ApplicationTests.java
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {
@Autowired
DemoProperties demoProperties;
@Test
public void contextLoads() {
System.out.println(demoProperties.getName());
}
}
So this Test prints myNameBad
when application.properties
is present, but when I delete or rename that file, the output is myNameGood
(which is desired).
Upvotes: 2
Views: 4473
Reputation: 131346
Properties coming from the default locations (here application.properties)
has higher priority as custom properties used in a class.
From the Spring Boot documentation :
72.3 Change the location of external properties of an application
A nice way to augment and modify this is to add @PropertySource annotations to your application sources. Classes passed to the SpringApplication static convenience methods, and those added using setSources() are inspected to see if they have @PropertySources, and if they do, those properties are added to the Environment early enough to be used in all phases of the ApplicationContext lifecycle. Properties added in this way have lower priority than any added using the default locations (e.g. application.properties), system properties, environment variables or the command line.
And this priority makes sense as configuration that you can provide at the runtime (such as application.properties
) should always be able to override configuration "hardcoded" in the application.
To test this mechanism, I created a test project,
To test a class or a behavior, you should rather write a unit test.
You could so use one of these way to override application.properties
values:
Renaming test.properties
into application.properties
and moving it into src/test/resources
.
using @TestPropertySource
. From the javadoc :
Test property sources have higher precedence than those loaded from the operating system's environment or Java system properties as well as property sources added by the application declaratively via @PropertySource or programmatically
Upvotes: 4