1. Overview
In this tutorial, weβll look at various ways to override the properties in Springβs tests.
Spring actually provides a number of solutions for this, so we have quite a bit to explore here.
2. Dependencies
Of course, in order to work with Spring tests, we need to add a test dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
This dependency also includes JUnit 5 for us.
3. Setup
First, weβll create a class in the application that will use our properties:
@Component
public class PropertySourceResolver {
@Value("${example.firstProperty}") private String firstProperty;
@Value("${example.secondProperty}") private String secondProperty;
public String getFirstProperty() {
return firstProperty;
}
public String getSecondProperty() {
return secondProperty;
}
}
Next, weβll assign values to them. We can do this by creating the application.properties in the src/main/resources:
example.firstProperty=defaultFirst
example.secondProperty=defaultSecond
4. Overriding a Property File
Now weβll override properties by putting the property file in the test resources. This file must be on the same classpath as the default one.
Additionally, it should contain all the property keys specified in the default file. Therefore, weβll add the application.properties file into the src/test/resources:
example.firstProperty=file
example.secondProperty=file
Letβs also add the test that will make use of our solution:
@SpringBootTest
public class TestResourcePropertySourceResolverIntegrationTest {
@Autowired private PropertySourceResolver propertySourceResolver;
@Test
public void shouldTestResourceFile_overridePropertyValues() {
String firstProperty = propertySourceResolver.getFirstProperty();
String secondProperty = propertySourceResolver.getSecondProperty();
assertEquals("file", firstProperty);
assertEquals("file", secondProperty);
}
}
This method is very effective when we want to override multiple properties from the file.
And if we donβt put the example.secondProperty in the file, the application context wonβt discover this property.
5. Spring Profiles
In this section, weβll learn how to handle our issue by using Spring Profiles. Unlike the previous method, this one merges properties from the default file and the profiled file.
First, letβs create an applicationβtest.properties file in the src/test/resources:
example.firstProperty=profile
Then weβll create a test that will use the test profile:
@SpringBootTest
@ActiveProfiles("test")
public class ProfilePropertySourceResolverIntegrationTest {
@Autowired private PropertySourceResolver propertySourceResolver;
@Test
public void shouldProfiledProperty_overridePropertyValues() {
String firstProperty = propertySourceResolver.getFirstProperty();
String secondProperty = propertySourceResolver.getSecondProperty();
assertEquals("profile", firstProperty);
assertEquals("defaultSecond", secondProperty);
}
}
This approach allows us to use both default and test values. Therefore, this is a great method when we need to override multiple properties from a file, but we still want to use the default ones too.
We can learn more about Spring profiles in our Spring Profiles article.
6. @SpringBootTest
Another way to override the property value is to use the @SpringBootTest annotation:
@SpringBootTest(properties = { "example.firstProperty=annotation" })
public class SpringBootPropertySourceResolverIntegrationTest {
@Autowired private PropertySourceResolver propertySourceResolver;
@Test
public void shouldSpringBootTestAnnotation_overridePropertyValues() {
String firstProperty = propertySourceResolver.getFirstProperty();
String secondProperty = propertySourceResolver.getSecondProperty();
Assert.assertEquals("annotation", firstProperty);
Assert.assertEquals("defaultSecond", secondProperty);
}
}
As we can see, the example.firstProperty has been overridden, while the example.secondProperty hasnβt been. Therefore, this is a great solution when we need to override only specific properties for the test. This is the only method that requires the use of Spring Boot.
7. TestPropertySourceUtils
In this section, weβll learn how to override properties by using the TestPropertySourceUtils class in the ApplicationContextInitializer.
The TestPropertySourceUtils comes with two methods that we can use to define a different property value.
Letβs create an initializer class that weβll use in our test:
public class PropertyOverrideContextInitializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
static final String PROPERTY_FIRST_VALUE = "contextClass";
@Override
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(
configurableApplicationContext, "example.firstProperty=" + PROPERTY_FIRST_VALUE);
TestPropertySourceUtils.addPropertiesFilesToEnvironment(
configurableApplicationContext, "context-override-application.properties");
}
}
Next, weβll add the context-override-application.properties file into src/test/resources:
example.secondProperty=contextFile
Finally, we should create a test class that will use our initializer:
@SpringBootTest
@ContextConfiguration(
initializers = PropertyOverrideContextInitializer.class,
classes = Application.class)
public class ContextPropertySourceResolverIntegrationTest {
@Autowired private PropertySourceResolver propertySourceResolver;
@Test
public void shouldContext_overridePropertyValues() {
final String firstProperty = propertySourceResolver.getFirstProperty();
final String secondProperty = propertySourceResolver.getSecondProperty();
assertEquals(PropertyOverrideContextInitializer.PROPERTY_FIRST_VALUE, firstProperty);
assertEquals("contextFile", secondProperty);
}
}
The example.firstProperty has been overridden from the inlined method.
The example.secondProperty has been overridden from the specific file in the second method. This approach allows us to define different property values when initializing the context.
8. Conclusion
In this article, we focused on the multiple ways we can override properties in our tests. We also discussed when to use each solution, or in some cases, when to mix them.
Of course, we have the @TestPropertySource annotation at our disposal as well.
