Override default Spring-Boot application.properties settings in Junit Test

I have a Spring-Boot application where the default properties are set in an application.properties file in the classpath (src/main/resources/application.properties).

I would like to override some default settings in my JUnit test with properties declared in a test.properties file (src/test/resources/test.properties)

I usualy have a dedicated Config Class for my Junit Tests, e.g.

package foo.bar.test;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import(CoreConfig.class)
@EnableAutoConfiguration
public class TestConfig {

}

I first thought that using @PropertySource("classpath:test.properties") in the TestConfig class would do the trick, but these properties will not overwrite the application.properties settings (see Spring-Boot Reference Doc - 23. Externalized Configuration).

Then I tried to use -Dspring.config.location=classpath:test.properties when invoking the test. That was successful - but I don't want to set this system property for each test execution. Thus I put it in the code

@Configuration
@Import(CoreConfig.class)
@EnableAutoConfiguration
public class TestConfig {

  static {
    System.setProperty("spring.config.location", "classpath:test.properties");
  }

}

which unfortunatly was again not successful.

There must be a simple solution on how to override application.properties settings in JUnit tests with test.properties that I must have overlooked.


Solution 1:

You can use @TestPropertySource to override values in application.properties. From its javadoc:

test property sources can be used to selectively override properties defined in system and application property sources

For example:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = ExampleApplication.class)
@TestPropertySource(locations="classpath:test.properties")
public class ExampleApplicationTests {

}

Solution 2:

Spring Boot automatically loads src/test/resources/application.properties, if following annotations are used

@RunWith(SpringRunner.class)
@SpringBootTest

So, rename test.properties to application.properties to utilize auto configuration.

If you only need to load the properties file (into the Environment) you can also use the following, as explained here

@RunWith(SpringRunner.class)
@ContextConfiguration(initializers = ConfigFileApplicationContextInitializer.class) 

[Update: Overriding certain properties for testing]

  1. Add src/main/resources/application-test.properties.
  2. Annotate test class with @ActiveProfiles("test").

This loads application.properties and then application-test.properties properties into application context for the test case, as per rules defined here.

Demo - https://github.com/mohnish82/so-spring-boot-testprops

Solution 3:

You can also use meta-annotations to externalize the configuration. For example:

@RunWith(SpringJUnit4ClassRunner.class)
@DefaultTestAnnotations
public class ExampleApplicationTests { 
   ...
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@SpringApplicationConfiguration(classes = ExampleApplication.class)
@TestPropertySource(locations="classpath:test.properties")
public @interface DefaultTestAnnotations { }

Solution 4:

Another approach suitable for overriding a few properties in your test, if you are using @SpringBootTest annotation:

@SpringBootTest(properties = {"propA=valueA", "propB=valueB"})