Spring-boot 利用 Spring profiles 允许例如为不同的环境进行单独的配置。我使用此功能的一种方法是配置测试数据库以供集成测试使用。但是我想知道是否有必要创建我自己的配置文件“测试”并在每个测试文件中明确激活此配置文件?现在我通过以下方式做到这一点:
在 src/main/resources 中创建 application-test.properties 在此处写入特定于测试的配置(现在只是数据库名称) 在每个测试文件中包括:@ActiveProfiles("test")
有没有更聪明/更简洁的方法?例如默认测试配置文件?
编辑 1:这个问题与 Spring-Boot 1.4.1 相关
据我所知,没有什么可以直接解决您的要求 - 但我可以提出一个可以帮助的建议:
您可以使用自己的测试注释,它是由 @SpringBootTest
和 @ActiveProfiles("test")
组成的 meta annotation。因此,您仍然需要专用配置文件,但要避免将配置文件定义分散到所有测试中。
此注释将默认为配置文件 test
,您可以使用元注释覆盖配置文件。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@SpringBootTest
@ActiveProfiles
public @interface MyApplicationTest {
@AliasFor(annotation = ActiveProfiles.class, attribute = "profiles") String[] activeProfiles() default {"test"};
}
另一种方法是定义一个基本(抽象)测试类,您的实际测试类将扩展:
@RunWith(SpringRunner.class)
@SpringBootTest()
@ActiveProfiles("staging")
public abstract class BaseIntegrationTest {
}
具体测试:
public class SampleSearchServiceTest extends BaseIntegrationTest{
@Inject
private SampleSearchService service;
@Test
public void shouldInjectService(){
assertThat(this.service).isNotNull();
}
}
这允许您提取的不仅仅是 @ActiveProfiles
注释。您还可以为不同类型的集成测试想象更专业的基类,例如数据访问层与服务层,或用于功能专业(常见的 @Before
或 @After
方法等)。
您可以将 application.properties 文件放在您的 test/resources 文件夹中。你在那里设置
spring.profiles.active=test
这是运行测试时的一种默认测试配置文件。
src/test/resources/application.properties
文件,则在运行测试时会忽略 src/main/resources/application.properties
内容。
application-test.properties
并仅覆盖您需要的属性。
spring.profiles.active=test
,否则不会被选中,就像答案所说的那样。
有两种方法。
从配置加载/
(2022 年更新,针对 Spring Boot 2.6 进行了测试)
除了以下方法,您还可以将配置添加到 src/test/resources/config/application.yml
src/
├── main/
│ ├── java/
│ │ └── ...
│ └── resources/
│ └── application.yml <- default properties, always loaded
└── test/
├── java/
│ └── ...
└── resources/
└── config/
└── application.yml <- test properties, will override the defaults
当你的应用启动时,Spring Boot 会自动从以下位置查找并加载 application.properties 和 application.yaml 文件: 从类路径 类路径根 类路径 /config 包 从当前目录 当前目录 当前目录下的 /config 子目录/config 子目录的直接子目录 该列表按优先级排序(较低项目的值覆盖较早的项目)。加载文件中的文档作为 PropertySources 添加到 Spring 环境中。
使用 spring.config.import 手动导入
(2021 年的原始答案,针对 Spring Boot 2.4 进行了测试)
一种解决方案是拥有 3 个属性文件并导入
src/main/resources/application.yml - 包含应用程序的默认道具
src/test/resources/application.yml - 将配置文件设置为“test”,并从“main”导入属性
src/test/resources/application-test.yml - 包含特定于测试的配置文件,它将覆盖“main”
以下是 src/test/resources/application.yml
的内容:
# for testing, set default profile to 'test'
spring.profiles.active: "test"
# and import the 'main' properties
spring.config.import: file:src/main/resources/application.yml
例如,如果 src/main/resources/application.yml
有内容
ip-address: "10.7.0.1"
username: admin
src/test/resources/application-test.yml
有
ip-address: "999.999.999.999"
run-integration-test: true
然后(假设没有其他配置文件)...
运行测试时,
profiles=test
--
ip-address=999.999.999.999
username=admin
run-integration-test=true
并且在正常运行应用程序时
profiles=none
--
ip-address=10.7.0.1
username=admin
run-integration-test <undefined>
注意:如果 src/main/resources/application.yml
包含 spring.profiles.active: "dev"
,那么它不会被 src/test/resources/application-test.yml
覆盖
src/test/resources/application.yml
文件,environment.getActiveProfiles()
仍会返回正确的测试配置文件,但如果我通过 @Value("${spring.profiles.active:}")
注释获得活动配置文件,它将为空。
一种说明性的方法(事实上,与@Compito 的原始答案相比,这是一个小小的 tweek):
在 test/resources/application-default.properties 中设置 spring.profiles.active=test。为测试添加 test/resources/application-test.properties 并仅覆盖您需要的属性。
application.properties
也被解析,然后是 test/resources/application-default.properties
,然后,因为检测到配置文件“test”,所以 test/resources/application-test.properties
被解析?否则,它不会解决 @Compito's answer 下评论的 @ciastek 的问题。
您可以将您的测试特定属性放入 src/test/resources/config/application.properties
。
此文件中定义的属性将在测试期间覆盖 src/main/resources/application.properties
中定义的属性。
如需详细了解此功能为何有效,请查看 Spring Boots docs。
如果你使用 maven,你可以在 pom.xml 中添加这个:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<argLine>-Dspring.profiles.active=test</argLine>
</configuration>
</plugin>
...
然后,maven 应该使用这个参数运行你的集成测试(*IT.java),并且 IntelliJ 将从激活这个配置文件开始 - 这样你就可以指定里面的所有属性
application-test.yml
你不应该需要“-default”属性。
要激活“测试”配置文件,请在 build.gradle 中写入:
test.doFirst {
systemProperty 'spring.profiles.active', 'test'
activeProfiles = 'test'
}
就我而言,我有不同的 application.properties 取决于环境,例如:
application.properties (base file)
application-dev.properties
application-qa.properties
application-prod.properties
并且 application.properties 包含一个属性 spring.profiles.active 来选择正确的文件。
对于我的集成测试,我在 test/resources
中创建了一个新的 application-test.properties
文件,并带有 @TestPropertySource({ "/application-test.properties" })
注释,这是负责根据我对这些测试的需要选择我想要的 application.properties 的文件
@ActiveProfiles
,而不是 @TestPropertySource
。
另一种以编程方式执行此操作的方法:
import static org.springframework.core.env.AbstractEnvironment.DEFAULT_PROFILES_PROPERTY_NAME;
@BeforeClass
public static void setupTest() {
System.setProperty(DEFAULT_PROFILES_PROPERTY_NAME, "test");
}
它工作得很好。
如果您只是想在通过 maven 构建时设置/使用默认配置文件,则传递参数 -Dspring.profiles.active=test
就像
mvn clean install -Dspring.profiles.active=dev
我通常使用通用代码和注释为所有集成测试完成一个基类。不要忘记将其设为 abstract
,以免实例化。例如:
@SpringBootTest
@Transactional
@AutoConfigureMockMvc
@ActiveProfiles("test")
public abstract class AbstractControllerTest {
@Autowired
protected MockMvc mockMvc;
protected ResultActions perform(MockHttpServletRequestBuilder builder) throws Exception {
return mockMvc.perform(builder);
}
}
// All annotations are inherited
class AccountControllerTest extends AbstractControllerTest {
....
我找到的最佳解决方案是这里的最后一个建议:https://inspeerity.com/blog/setting-default-spring-profile-for-tests-with-override-option/ 作者还非常清楚地描述了这个问题,并讨论了我能想到的所有其他方法的缺点。
在您的测试资源中创建一个文件 application-default.properties
,其中包含一行:
spring.profiles.active=test
这利用了这样一个事实,即如果没有明确设置其他配置文件,Spring 会自动启用“默认”配置文件。现在,您的 application-test.properties
文件将默认用于所有测试。
在 application.properties 文件中添加 spring.profiles.active=tests
,您可以在 spring boot 应用程序中添加多个属性文件,如 application-stage.properties
、application-prod.properties
等。您可以在 application.properties 文件中指定要通过添加 { 4} 或 spring.profiles.active=prod
您还可以通过提供以下命令在运行 Spring Boot 应用程序时传递配置文件:
java -jar
-Dspring.profiles.active=local
build/libs/turtle-rnr-0.0.1-SNAPSHOT.jar
根据配置文件名称选择属性文件,在上述情况下,通过配置文件 local
考虑 application-local.properties
文件