1. Overview
1.概述
In this tutorial, we’ll look at various ways to override the properties in Spring’s tests.
在本教程中,我们将研究覆盖Spring测试中的属性的各种方法。
Spring actually provides a number of solutions for this, so we have quite a bit to explore here.
实际上,Spring为此提供了许多解决方案,所以我们在这里有相当多的内容可以探讨。
2. Dependencies
2.依赖性
Of course, in order to work with Spring tests, we need to add a test dependency:
当然,为了与Spring测试一起工作,我们需要添加一个测试依赖关系。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.7.2</version>
<scope>test</scope>
</dependency>
This dependency also includes JUnit 5 for us.
这个依赖关系也包括我们的JUnit 5。
3. Setup
3.设置
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:
接下来,我们将为它们赋值。我们可以通过在src/main/resources中创建application.properties来做到这一点:。
example.firstProperty=defaultFirst
example.secondProperty=defaultSecond
4. Overriding a Property File
4.覆盖一个属性文件
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.
现在我们将通过把属性文件放在测试资源中来覆盖属性。这个文件必须与默认文件在同一classpath。
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:
此外,它应该包含默认文件中指定的所有属性键。因此,我们将把application.properties文件添加到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.
而如果我们不把example.secondProperty放在文件中,应用程序上下文就不会发现这个属性。
5. Spring Profiles
5.Spring型材
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.
在本节中,我们将学习如何通过使用Spring Profiles来处理我们的问题。与之前的方法不同, 这个方法合并了默认文件和剖析文件中的属性。
First, let’s create an application–test.properties file in the src/test/resources:
首先,让我们在src/test/resources中创建一个application–test.properties文件:。
example.firstProperty=profile
Then we’ll create a test that will use the test profile:
然后我们将创建一个测试,使用test配置文件。
@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.
我们可以在我们的Spring Profiles文章中了解更多关于Spring配置文件的信息。
6. @SpringBootTest
6.@SpringBootTest
Another way to override the property value is to use the @SpringBootTest annotation:
另一种覆盖属性值的方法是使用 @SpringBootTest 注释。
@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.
我们可以看到,example.firstProperty已经被覆盖,而example.secondProperty还没有被覆盖。因此,当我们只需要覆盖测试的特定属性时,这是一个很好的解决方案。这是唯一需要使用Spring Boot的方法。
7. TestPropertySourceUtils
7.TestPropertySourceUtils
In this section, we’ll learn how to override properties by using the TestPropertySourceUtils class in the ApplicationContextInitializer.
在本节中,我们将学习如何通过使用ApplicationContextInitializer中的TestPropertySourceUtils类来重写属性。
The TestPropertySourceUtils comes with two methods that we can use to define a different property value.
TestPropertySourceUtils带有两个方法,我们可以用它们来定义不同的属性值。
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:
接下来,我们将把context-overrid-application.properties文件添加到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.
example.firstProperty已经从inlined方法中重写。
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.
example.secondProperty已经在第二个方法中从特定的文件中被重写了。这种方法允许我们在初始化上下文时定义不同的属性值。
8. Conclusion
8.结语
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.
当然,我们也有@TestPropertySource注解供我们使用。
As always, the code for the examples in this article is available over on GitHub.
一如既往,本文中示例的代码可在GitHub上获得。