如何使用@IfProfileValue 来测试配置文件是否处于活动状态?
How can I use @IfProfileValue to test if a Profile is active?
令人困惑的是 @IfProfileValue
与 @Profile
或 @ActiveProfiles
无关。 @Profile
测试配置文件是否处于活动状态,@ActiveProfiles
将其设置为活动状态,@IfProfileValue
允许您检查 Spring Environment
中的内容。唔?我会弃用所有这些并添加新的 @IfEnvironment
、@IfProfile
和 @ActivateProfiles
。
撇开评论不谈,我如何使用 @IfProfileValue
来检测我的配置文件是否处于活动状态?我现在没有在这个项目上使用 Spring Boot。答案应该显示代码,如果配置文件被激活为 @ActiveProfiles( "test" )
,我们假设我希望测试 运行。
我试过 @IfProfileValue(name = "activeProfiles", value = "test")
但似乎跳过了测试,这意味着它不匹配。我推测问题可能与 ActiveProfiles
是 Collection
.
这一事实有关
So confusingly @IfProfileValue
has nothing to do with @Profile
or
@ActiveProfiles
.
没错,我在这里详细解释了这一点:
...我假设你已经看到了,因为你昨天对我的回答发表了评论。
之所以@IfProfileValue
与@Profile
或@ActiveProfiles
无关,是因为框架的进化。详情见下文。
@Profile
tests to see if a profile is active,
@ActiveProfiles
sets them as active, and @IfProfileValue
allows
you to check things in Spring Environment
.
这些说法并不完全正确,尤其是最后一部分。
@Profile
用于有选择地启用一个组件(例如,@Service
等),@Configuration
class 或 @Bean
方法,如果一个命名的 bean 定义配置文件 在 Spring Environment
中处于活动状态 ApplicationContext
。此注释与测试没有直接关系:@Profile
应该 而不是 用于测试 class.
@ActiveProfiles
用于指定在加载 ApplicationContext
进行集成测试。
@IfProfileValue
不 允许您检查 Spring Environment
中的内容。我不确定您为什么会这样假设,因为 none 框架中的文档说明了这一点。正如我在上述主题中所述:
请注意 @IfProfileValue
是在 Spring Framework 2.0 中引入的,long 在 bean 定义配置文件的概念之前,并且 @ActiveProfiles
首次在 Spring Framework 3.1 中引入。
在上述帖子中,我还指出了以下内容:
术语 'profile' 在考虑 @IfProfileValue
的语义时可能会产生误导。关键是要考虑 'test groups'(就像 TestNG 中的那样)而不是 'profiles'。请参阅 JavaDoc for @IfProfileValue.
中的示例
how can I use @IfProfileValue
to detect whether i have a profile active?
这取决于,并且......我假设你说 bean 定义配置文件 当你说 "profile".
如果您正在使用 @ActiveProfiles
为您的测试设置 bean 定义配置文件,您目前无法使用 @IfProfileValue
来确定 bean 定义配置文件 处于活动状态,因为通过 @ActiveProfiles
配置的 bean 定义配置文件 直接在测试的 ApplicationContext
中设置,而不是作为一个 Java 系统 属性.
但是,如果您通过 spring.profiles.active
系统 属性 设置 bean 定义配置文件 仅,那么 将 可以使用 @IfProfileValue
来确定 bean 定义配置文件 是否处于活动状态,因为实际上 @IfProfileValue
使用系统属性。例如,您可以使用以下内容:
@IfProfileValue(name = "spring.profiles.active", value = "test")
I tried @IfProfileValue(name = "activeProfiles", value = "test")
but
that seems to have the test skipped, which means it's not matching.
那是行不通的,因为 activeProfiles
是不正确的 属性 名称。正确的系统 属性 名称是 spring.profiles.active
。有关详细信息,请参阅 AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME
。
@IfProfileValue
与 @ActiveProfiles
不协调这一事实是 Spring 团队的一个已知问题。请查阅以下 JIRA 问题以获取更多详细信息,如果您愿意,也可以加入讨论。
- https://jira.spring.io/browse/SPR-7754
- https://jira.spring.io/browse/SPR-8982
- https://jira.spring.io/browse/SPR-11677
希望这能为您澄清情况!
Sam(Spring TestContext Framework 的作者)
山姆成功了。 (以及几年前被接受和回答的事实)
要补充的一件事是,如果您想将系统属性传递给您的测试,如果您使用像 gradle 这样的构建工具,让它们传播到 JVM 可能需要额外的步骤.
//build.gradle
tasks.withType(Test) {
systemProperties System.properties
}
然后在集成测试中一切照常
//MyIntegrationTest.class
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("integration")
@IfProfileValue(name = "run.integration.tests", value = "true")
public class MyIntegrationTest {
@Test
public void myTest(){ ... }
}
最后,您可以使用指定的 属性 从终端执行测试。
$> ./gradlew clean test -Drun.integration.tests=true
我最喜欢 @IfProfileValue
而不是抓取 System.property 并手动检查 assumeTrue/False
的一点是没有加载 Spring 上下文(或 flyway/other您可能拥有的迁移)保持单元测试快速。
不幸的是,根据我的经验,测试对@IfProfileValue
的依赖
@Test
@IfProfileValue(name="spring.profiles.active", values={"test"})
仅当您将 spring.profiles.active 设置为 JVM 属性 时才有效,如下所示:
-Dspring.profiles.active="test"
@IfProfileValue just ignores spring.profiles.active from application.properties/yml.
使用 junit5 时,可以根据活动配置文件有条件地启用测试:
@EnabledIf(expression =
"#{environment.acceptsProfiles(T(org.springframework.core.env.Profiles).of('someprofile'))}",
loadContext = true)
class MyTest {
...
}
这会检查 someprofile
是否处于活动状态,这与检查 spring.profiles.active
属性 工作事件不同(如果启用了多个配置文件)。这会检查 someprofile
是否在当前活动的配置文件中。
为了使其更具可读性,可以使用 spring meta-annotation。先定义注解
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@EnabledIf(expression =
"#{environment.acceptsProfiles(T(org.springframework.core.env.Profiles).of('someprofile'))}",
loadContext = true)
public @interface EnabledIfSomeProfile {
}
然后在测试中使用它 类:
@EnableIfSomeProfile
class MyTest {
...
}
令人困惑的是 @IfProfileValue
与 @Profile
或 @ActiveProfiles
无关。 @Profile
测试配置文件是否处于活动状态,@ActiveProfiles
将其设置为活动状态,@IfProfileValue
允许您检查 Spring Environment
中的内容。唔?我会弃用所有这些并添加新的 @IfEnvironment
、@IfProfile
和 @ActivateProfiles
。
撇开评论不谈,我如何使用 @IfProfileValue
来检测我的配置文件是否处于活动状态?我现在没有在这个项目上使用 Spring Boot。答案应该显示代码,如果配置文件被激活为 @ActiveProfiles( "test" )
,我们假设我希望测试 运行。
我试过 @IfProfileValue(name = "activeProfiles", value = "test")
但似乎跳过了测试,这意味着它不匹配。我推测问题可能与 ActiveProfiles
是 Collection
.
So confusingly
@IfProfileValue
has nothing to do with@Profile
or@ActiveProfiles
.
没错,我在这里详细解释了这一点:
...我假设你已经看到了,因为你昨天对我的回答发表了评论。
之所以@IfProfileValue
与@Profile
或@ActiveProfiles
无关,是因为框架的进化。详情见下文。
@Profile
tests to see if a profile is active,@ActiveProfiles
sets them as active, and@IfProfileValue
allows you to check things in SpringEnvironment
.
这些说法并不完全正确,尤其是最后一部分。
@Profile
用于有选择地启用一个组件(例如,@Service
等),@Configuration
class 或 @Bean
方法,如果一个命名的 bean 定义配置文件 在 Spring Environment
中处于活动状态 ApplicationContext
。此注释与测试没有直接关系:@Profile
应该 而不是 用于测试 class.
@ActiveProfiles
用于指定在加载 ApplicationContext
进行集成测试。
@IfProfileValue
不 允许您检查 Spring Environment
中的内容。我不确定您为什么会这样假设,因为 none 框架中的文档说明了这一点。正如我在上述主题中所述:
请注意 @IfProfileValue
是在 Spring Framework 2.0 中引入的,long 在 bean 定义配置文件的概念之前,并且 @ActiveProfiles
首次在 Spring Framework 3.1 中引入。
在上述帖子中,我还指出了以下内容:
术语 'profile' 在考虑 @IfProfileValue
的语义时可能会产生误导。关键是要考虑 'test groups'(就像 TestNG 中的那样)而不是 'profiles'。请参阅 JavaDoc for @IfProfileValue.
how can I use
@IfProfileValue
to detect whether i have a profile active?
这取决于,并且......我假设你说 bean 定义配置文件 当你说 "profile".
如果您正在使用 @ActiveProfiles
为您的测试设置 bean 定义配置文件,您目前无法使用 @IfProfileValue
来确定 bean 定义配置文件 处于活动状态,因为通过 @ActiveProfiles
配置的 bean 定义配置文件 直接在测试的 ApplicationContext
中设置,而不是作为一个 Java 系统 属性.
但是,如果您通过 spring.profiles.active
系统 属性 设置 bean 定义配置文件 仅,那么 将 可以使用 @IfProfileValue
来确定 bean 定义配置文件 是否处于活动状态,因为实际上 @IfProfileValue
使用系统属性。例如,您可以使用以下内容:
@IfProfileValue(name = "spring.profiles.active", value = "test")
I tried
@IfProfileValue(name = "activeProfiles", value = "test")
but that seems to have the test skipped, which means it's not matching.
那是行不通的,因为 activeProfiles
是不正确的 属性 名称。正确的系统 属性 名称是 spring.profiles.active
。有关详细信息,请参阅 AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME
。
@IfProfileValue
与 @ActiveProfiles
不协调这一事实是 Spring 团队的一个已知问题。请查阅以下 JIRA 问题以获取更多详细信息,如果您愿意,也可以加入讨论。
- https://jira.spring.io/browse/SPR-7754
- https://jira.spring.io/browse/SPR-8982
- https://jira.spring.io/browse/SPR-11677
希望这能为您澄清情况!
Sam(Spring TestContext Framework 的作者)
山姆成功了。 (以及几年前被接受和回答的事实)
要补充的一件事是,如果您想将系统属性传递给您的测试,如果您使用像 gradle 这样的构建工具,让它们传播到 JVM 可能需要额外的步骤.
//build.gradle
tasks.withType(Test) {
systemProperties System.properties
}
然后在集成测试中一切照常
//MyIntegrationTest.class
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("integration")
@IfProfileValue(name = "run.integration.tests", value = "true")
public class MyIntegrationTest {
@Test
public void myTest(){ ... }
}
最后,您可以使用指定的 属性 从终端执行测试。
$> ./gradlew clean test -Drun.integration.tests=true
我最喜欢 @IfProfileValue
而不是抓取 System.property 并手动检查 assumeTrue/False
的一点是没有加载 Spring 上下文(或 flyway/other您可能拥有的迁移)保持单元测试快速。
不幸的是,根据我的经验,测试对@IfProfileValue
的依赖@Test
@IfProfileValue(name="spring.profiles.active", values={"test"})
仅当您将 spring.profiles.active 设置为 JVM 属性 时才有效,如下所示: -Dspring.profiles.active="test"
@IfProfileValue just ignores spring.profiles.active from application.properties/yml.
使用 junit5 时,可以根据活动配置文件有条件地启用测试:
@EnabledIf(expression =
"#{environment.acceptsProfiles(T(org.springframework.core.env.Profiles).of('someprofile'))}",
loadContext = true)
class MyTest {
...
}
这会检查 someprofile
是否处于活动状态,这与检查 spring.profiles.active
属性 工作事件不同(如果启用了多个配置文件)。这会检查 someprofile
是否在当前活动的配置文件中。
为了使其更具可读性,可以使用 spring meta-annotation。先定义注解
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@EnabledIf(expression =
"#{environment.acceptsProfiles(T(org.springframework.core.env.Profiles).of('someprofile'))}",
loadContext = true)
public @interface EnabledIfSomeProfile {
}
然后在测试中使用它 类:
@EnableIfSomeProfile
class MyTest {
...
}