custom properties in junit test, something like application.setDefaultProperties - spring-boot

I'm creating unit/integration test in Spring boot app and have difficulty to add test properties.
this is how main application get properties from src/main/resources/config.json file.
Config config = new AppConfig().config();
if (config == null) {
System.exit(1);
}
application.setDefaultProperties(config.getSpringProperties());
application.run(args);
I'd like to put test config file under src/text/resources/ and use it for integration test with MockMvc. Is there any way to do it?
config.getSpringProperties()
returns Map

Spring boot automatically resolves test properties from src/test/resources/application.properties

Update:
You can define custom properties locations with annotations like #TestPropertySource or #SpringBootTest(properties
Here some resource on the topic:
https://www.baeldung.com/properties-with-spring
Old:
Just add a file named application-test.properties or application-test.yml and annotate the test with #ActiveProfiles("test").
By this you can even have multiple profiles. Just add the #ActiveProfiles("xyz") and name the application properties file application-xyz.yml

Related

In which class in the source code of spring-boot or spring is the application.yml or application.properties file processed?

In which class in the source code of spring-boot or spring is the application.yml file or application.properties processed?
For spring boot (version 2.x) the application properties are loaded from the environment into the context via a PropertySourceLoader.
In for example the spring-boot-2.6.3.jar we can find the following file:
META-INF/spring.factories
# PropertySource Loaders
org.springframework.boot.env.PropertySourceLoader=\
org.springframework.boot.env.PropertiesPropertySourceLoader,\
org.springframework.boot.env.YamlPropertySourceLoader
Where PropertiesPropertySourceLoader loads .properties and .xml files, and YamlPropertySourceLoader loads .yml and .yaml.
These are loaded with the SpringFactoriesLoader, which we can see in action in org.springframework.boot.context.config.ConfigFileApplicationListener (deprecated) or org.springframework.boot.context.config.StandardConfigDataLocationResolver (via ConfigDataEnvironmentPostProcessor -> ConfigDataEnvironment -> ConfigDataLocationResolvers) :
this.propertySourceLoaders = SpringFactoriesLoader.loadFactories(PropertySourceLoader.class,
getClass().getClassLoader());
You can read in the ConfigFileApplicationListener JavaDoc that the properties are indeed loaded with this class:
EnvironmentPostProcessor that configures the context environment by loading properties from well known file locations. By default properties will be loaded from 'application.properties' and/or 'application.yml' files in the following locations:
file:./config/
file:./config/*/
file:./
classpath:config/
classpath:
...
If you're interested in context loading from the environment in spring(boot), I suggest you setup your project with maven, download the sources jars, and have a look around in the mentioned factories file. You will find more relevant code in the org.springframework.boot.env and org.springframework.boot.context (config and properties) packages.
You can find your application.yml or application.properties at the src/main/resources. You can have as many as possible configurations for your spring boot application for every case. Lets assume that you have 3 local-profiles like demo, production and server, so you made 3 configuration and assumingyou set for active profile the demo at the application.yml . I hope you get the idea. Its the first thing that actually is running before the springboot is up.
Please look the officials docs !

Spring Boot application to have separated multiple property files

Coming from Play Framework, a handy feature that has helped to organize the application configurations was to use includes (Link) to spilt the various configurations into multiple .conf files as below.
application.conf Content
include "play-http.conf"
include "play-modules.conf"
include "play-i18n.conf"
include "authentication.conf"
include "hbase.conf"
include "custom-caches.conf"
include "custom-filters.conf"
#Any other root level application configurations
Is there an equivalent to this in Spring Boot .properties files?
From Spring 2.4, we can create multiple properties file for each profiles as below.
application-main1.properties
application-sub1.properties
application-sub2.properties
And then in default application.properties file we can group all sub profiles and activate the main profile
spring.profiles.group.main1=sub1,sub2
spring.profiles.active=main1
I am not sure if we can group sub profiles under default profile. You can try out
spring.profiles.group.default=sub1,sub2
This way you don't need to have another file for main profile.
I use yaml configuration files myself but I think that the configuration is mostly similar. You should take a look at the PropertySourcesPlaceholderConfigurer.
I have defined a PropertySourcesPlaceholderConfigurer bean to use a configuration override file located outside of the jar. Anything that is in the override file will be used instead of the default configuration. Anything that is not in the override file is still retrieved from the default configuration file. I think you can create a similar bean to achieve what you are looking for.
Here's my code:
#Bean
static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
var properties = new PropertySourcesPlaceholderConfigurer();
properties.setLocation(new FileSystemResource("./application.yaml"));
properties.setIgnoreResourceNotFound(true);
return properties;
}
For my use case, I only needed to define one properties location, but it is also possible to specify multiple locations:
...
properties.setLocations(Resource... locations);
...
My requirement was simply achieved using the spring.config.import (Link).
I created multiple property files such as hbase.properties, custom-caches.properties etc. And then in my application.properties imported those additional property files as below.
spring.config.import=hbase.properties,custom-caches.properties
#Any other properties in the application.properties file
Thanks

Different YAML configuration file for junit test using an Externalized configuration in Spring Boot

I am following a tutorial on using external configuration files for Spring Boot. I got everything to work exactly as intended but I'm having issues overriding the default YAML config for my tests.
Could someone please point me in the right direction or advice if using '#PropertySource' is the best way to load config files into the project (There is a bunch of properties and I would like to keep the application.yaml as clean as possible)
Project Structure:
src: - main/resources/foo.yml <-- always loads this one
- test/resources/foo.yml <-- never loads
What I tried:
#PropertySource(value = "classpath:foo.yml")
Doesn't load test/resoruces/foo.yml to the classpath
ActiveProfiles()
How I usually change config properties but in this case, it's not a profile so it doesn't work.
Details:
Spring boot: 2.2.7.RELEASE
Try this:
#TestPropertySource(properties = { "spring.config.location=classpath:foo.yml" })

SpringBootTest: how to use application-test.yaml and inherit missing values from application.yaml

I am trying to run an integration test using the annotations :
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
#ActiveProfiles({ "test" }).
The problem I have is that the application loads by using the spring profile "test"
I have two config files:
application.yaml
application-test.yaml
application.yaml contains:
xyz:
list:
- class-name: com.any.prod.ClassName1
jndi-name: com/ws/ClassName1
- class-name: com.any.prod.ClassName2
jndi-name: com/ws/ClassName2
and the other file doesn't contain these values.
these valuer are used by a library that i use, and not directly by my application.
when I load the test with the "test" profile enabled the values from application.yaml are not picked up. If I add the same values to application-test.yaml they are picked up during the binding process.
These are the properties that are picked up:
xyz.list[0].class-name: com.any.prod.ClassName1 (loaded from application-test.yaml)
xyz.list[0].jndi-name: com/ws/ClassName1 (loaded from application-test.yaml)
xyz.list[1].class-name: com.any.prod.ClassName2 (loaded from application-test.yaml)
xyz.list[1].jndi-name: com/ws/ClassName2 (loaded from application-test.yaml)
xyz.list (loaded from application.yaml)
Unfortunately the last entry makes the validation of the properties fail.
Does anyone has in mind what can I do to solve this mystery?
At this point my understanding of how configuration yaml files are wrong (at least for the testing case - inheritance appears to be working just fine when we deploy our app)
You can achieve this by using the annotation #TestPropertySource .

Spring Boot profile specific properties

I'm using Sprint Boot, and would like to have multiple profile specific property files. The docs state:
In addition to application.properties files, profile specific
properties can also be defined using the naming convention
application-{profile}.properties.
http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-external-config-profile-specific-properties
However I have multiple properties files (e.g. db.properties). I'm loading currently load this non-profile specific file as:
#Configuration
#PropertySource( {"classpath:db.properties"} )
class DataSourceConfig {
#Value("db.server") String server;
...
}
How can I combine these two things together, so it loads db-dev.properties like Spring Boot does for application.properties
It sounds like it should be easy, but I can't work out how to do it?!
Java -jar my-spring-boot.jar --spring.profiles.active=test you can set profile.active=your environment via commandline
I just saw that you use #PropertySource. The docs say:
Profile specific variants of both application.properties (or application.yml) and files referenced via #ConfigurationProperties are considered as files are loaded.

Resources