I'd like to write some tests that check the XML Spring configuration of a deployed WAR. Unfortunately some beans require that some environment variables or system properties are set. How can I set an environment variable before the spring beans are initialized when using the convenient test style with @ContextConfiguration?
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:whereever/context.xml") public class TestWarSpringContext { ... }
If I configure the application context with annotations, I don't see a hook where I can do something before the spring context is initialized.
Environment-Specific Properties File. If we need to target different environments, there's a built-in mechanism for that in Boot. We can simply define an application-environment. properties file in the src/main/resources directory, and then set a Spring profile with the same environment name.
If your test relies on system properties you could set them and unset them in 'before' and 'after' lifecycle methods. In Junit5, setting system properties for all tests in a test case might look like this: @BeforeAll public static void setSystemProperties() { // set the system properties // ... }
Spring - Environment Properties. Spring attempts to unify all name/value property pairs access into org.springframework.core.env.Environment. The properties source can be java.util.Properties, loaded from a file or Java system/env properties or java.util.Map. If we are in the Servlet container environment, the source can be javax.servlet.
Environment is an interface representing the environment in which the current application is running. It can be use to get profiles and properties of the application environment. In this sample case, we have a JAVA_HOME environment variable defined. This is the project structure of the Spring Boot application. This is the Maven build file.
Ideally, application.properties contains all common properties which are accessible for all environments and environment related properties only works on specifies environment. therefore the order of loading these properties files will be in such way - application.properties -> application. {spring.profiles.active}.properties.
By default, system properties have precedence over environment variables, so if the foo property happens to be set in both places during a call to env.getProperty ("foo"), the system property value will 'win' and be returned preferentially over the environment variable.
You can initialize the System property in a static initializer:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:whereever/context.xml") public class TestWarSpringContext { static { System.setProperty("myproperty", "foo"); } }
The static initializer code will be executed before the spring application context is initialized.
The right way to do this, starting with Spring 4.1, is to use a @TestPropertySource
annotation.
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:whereever/context.xml") @TestPropertySource(properties = {"myproperty = foo"}) public class TestWarSpringContext { ... }
See @TestPropertySource in the Spring docs and Javadocs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With