1. Overview

Spring brings many features to help us with testing our code. Sometimes we need to use particular configuration properties in order to set up the desired scenario in our test cases.

In these situations, we can make use of the @TestPropertySource annotation. With this tool, we can define configuration sources that have higher precedence than any other source used in the project.

Hence, in this short tutorial, we’ll see examples where we use this annotation. Also, we’ll analyze its default behavior and the main attributes it supports.

To learn more about testing in Spring Boot, we suggest having a look at our ‘Testing in Spring Boot’ tutorial.

2. Dependencies

The easiest way to include all the required libraries in our project is by adding the spring-boot-starter-test artifact in our pom.xml file:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

We can check Maven Central to verify we’re using the latest version of the starter library.

3. How to Use @TestPropertySource

Let’s imagine we’re using the value of a property by injecting it using the @Value Spring annotation:

@Component
public class ClassUsingProperty {
    
    @Value("${baeldung.testpropertysource.one}")
    private String propertyOne;
    
    public String retrievePropertyOne() {
        return propertyOne;
    }
}

We’ll then use the @TestPropertySource class-level annotation to define a new configuration source and override the value of that property:

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = ClassUsingProperty.class)
@TestPropertySource
public class DefaultTest {

    @Autowired
    ClassUsingProperty classUsingProperty;

    @Test
    public void givenDefaultTPS_whenVariableRetrieved_thenDefaultFileReturned() {
        String output = classUsingProperty.retrievePropertyOne();

        assertThat(output).isEqualTo("default-value");
    }
}

Typically, whenever we use this test annotation we will also include the @ContextConfiguration one so as to load and configure the ApplicationContext for the scenario.

By default, the @TestPropertySource annotation tries to load a properties file relative to the class that declared the annotation.

In this case, for example, if our test class is in the com.baeldung.testpropertysource package, then we’ll need the file com/baeldung/testpropertysource/DefaultTest.properties in our classpath.

Let’s add it to our resources folder then:

# DefaultTest.properties
baeldung.testpropertysource.one=default-value

Additionally, we can change the default configuration file location, or add extra properties that will have even higher precedence:

@TestPropertySource(locations = "/other-location.properties",
  properties = "baeldung.testpropertysource.one=other-property-value")

It is possible to pass multiple custom properties. We can achieve this by using an array literal:

@TestPropertySource(
  locations = "/other-location.properties",
  properties = """
    baeldung.testpropertysource.one=one
    baeldung.testpropertysource.two=two
  """)
public class MultiplePropertiesInPropertySourceTextBlockIntegrationTest {

With Java 15 and Spring 6.1.0, or newer, we have the option to use a multi-line text block:

@TestPropertySource(
  locations = "/other-location.properties",
  properties = """
    baeldung.testpropertysource.one=one
    baeldung.testpropertysource.two=two
    """)
public class MultiplePropertiesInPropertySourceTextBlockIntegrationTest {

Finally, we can specify whether we want to inherit locations and properties values from superclasses or not. Hence, we can toggle the inheritLocations and inheritProperties attributes, which are true by default.

4. Conclusion

With this simple example, we’ve learned how to use the @TestPropertySource Spring annotation effectively.

We can find examples for the different scenarios in our Github repository.