Set System Properties or Environment Variables Before Property Placeholder with SpringJunit4ClassRunner

15,663

Solution 1

Thinking of ,

  1. Extending SpringJUnit4ClassRunner and setting the system property configOverride in its constructor/initialization block
  2. Then passing ExtendedSpringJUnit4ClassRunner to @RunWith

Solution 2

One other alternative is setting the environment property in a @BeforeClass annotated method, which will be invoked before the Context Configuration happens.

@BeforeClass
public static void setSystemProps() {
    System.setProperty("configOverride", "yourVal");
}

Solution 3

Here's what I ended up doing - I didn't have to change any unit test classes. Unfortunately, I didn't set the "configOverride" property (see AhamedMustafaM's answer for one way to do that) and instead went with overriding the original property placeholder definition (I tried again after my initial failed attempts and got it to work).

I added the following line to my testContext.xml:

<!-- import the main app context -->
<import resource="classpath:appContext.xml" />

<!-- this is the line i added -->
<context:property-placeholder order="-999"
        location="classpath:testConfig.properties"
        ignore-unresolvable="true" />

Note the order="-999" attribute, which is used to ensure priority over the original property-placeholder definition(s). Also I set "ignore-unresolvable" to "true" to delegate any unresolvable properties to the original placeholder configurer.

Share:
15,663
andy
Author by

andy

My passion is making things simple, neat, and coherent. Disclaimer: My opinions are my own and do not reflect the views of my employer.

Updated on June 17, 2022

Comments

  • andy
    andy almost 2 years

    I have a main app-context.xml that defines a property placeholder with two locations: default properties file and an optional override file:

    <context:property-placeholder
            location="classpath:config.properties,${configOverride}"
            ignore-resource-not-found="true" />
    

    The optional override location allows specifying another properties file (e.g. "-DconfigOverride=file:/home/app/config.properties") with only the properties that should be overridden.

    For my unit tests, I'm using a test context that imports app-context.xml:

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = {"classpath:test-context.xml"})
    public class UserServiceTest {
        ...
    }
    

    How can I set system properties or environment variables within the application before the application context is loaded? I would like to achieve the same effect as setting "-DconfigOverride=classpath:testConfig.properties" across all test classes without having to specify a command line arg, if possible.