当与 SpringExtension 和 JUnit Jupiter(即 JUnit 5 中的编程模型)结合使用时,支持以下注解:
- @SpringJUnitConfig
- @SpringJUnitWebConfig
- @TestConstructor
- @NestedTestConfiguration
- @EnabledIf
- @DisabledIf
@SpringJUnitConfig
@SpringJUnitConfig
是一个组合注解,它结合了 JUnit Jupiter 的 @ExtendWith(SpringExtension.class)
和 Spring TestContext 框架的 @ContextConfiguration
。它可以作为 @ContextConfiguration
的替代品在类的层面上使用。关于配置选项,@ContextConfiguration
和 @SpringJUnitConfig
之间的唯一区别是,组件类可以用 @SpringJUnitConfig
中的 value 属性来声明。
下面的例子展示了如何使用 @SpringJUnitConfig
注解来指定一个配置类:
@SpringJUnitConfig(TestConfig.class) // 指定配置类
class ConfigurationClassJUnitJupiterSpringTests {
// class body...
}
更多细节请参见 Context Management 以及 [@SpringJUnitConfig](https://docs.spring.io/spring-framework/docs/5.3.15/javadoc-api/org/springframework/test/context/junit/jupiter/SpringJUnitConfig.html)
和@ContextConfiguration
的javadoc。
@SpringJUnitWebConfig
@SpringJUnitWebConfig
是一个组合注解,它将 JUnit Jupiter 中的 @ExtendWith(SpringExtension.class)
与 Spring TestContext 框架中的 @ContextConfiguration
和 @WebAppConfiguration
相结合。你可以在类的层面上使用它,作为 @ContextConfiguration
和@WebAppConfiguration
的直接替代。关于配置选项,@ContextConfiguration
和@SpringJUnitWebConfig
的唯一区别是,你可以通过使用 @SpringJUnitWebConfig
的 value 属性来声明组件类。此外,你只能通过使用@SpringJUnitWebConfig
中的 resourcePath 属性来覆盖 @WebAppConfiguration
的值属性。
下面的例子展示了如何使用 @SpringJUnitWebConfig
注解来指定一个配置类:
@SpringJUnitWebConfig(TestConfig.class)
class ConfigurationClassJUnitJupiterSpringWebTests {
// class body...
}
下面的例子显示了如何使用 @SpringJUnitWebConfig
注解来指定一个配置文件的位置:
@SpringJUnitWebConfig(locations = "/test-config.xml")
class XmlJUnitJupiterSpringWebTests {
// class body...
}
更多细节请参见 Context Management 以及 @SpringJUnitWebConfig、@ContextConfiguration 和 @WebAppConfiguration 的 javadoc。
@TestConstructor
@TestConstructor
是一个类型级别的注解,用于配置测试类构造函数的参数如何从测试的 ApplicationContext 中的组件自动连接。
如果 @TestConstructor
在测试类上不存在或元存在,将使用默认的测试构造函数自动连接模式。关于如何改变默认模式的细节,见下面的提示。然而,请注意,构造函数上的 @Autowired
局部声明优先于 @TestConstructor
和默认模式。
:::tips
改变默认的测试构造器自动布线模式
默认的测试构造器自动布线模式可以通过设置 spring.test.constructor.autowire.mode
JVM 系统属性为 all 来改变。另外,也可以通过 SpringProperties 机制设置默认模式。
从 Spring Framework 5.3 开始,默认模式也可以作为 JUnit 平台配置参数进行配置。
如果 spring.test.constructor.autowire.mode
属性没有设置,测试类构造器将不会自动自动连接。
:::
:::info 从 Spring 框架 5.2 开始,@TestConstructor 只支持与 SpringExtension 一起使用 JUnit Jupiter。请注意,SpringExtension 通常会自动为你注册,例如,在使用 @SpringJUnitConfig 和 @SpringJUnitWebConfig 等注解或 Spring Boot Test 的各种测试相关注解时。 :::
@NestedTestConfiguration
@NestedTestConfiguration
是一个类型级注解,用于配置 Spring 测试配置注解在内部测试类的包围类层次结构中的处理方式。
如果 @NestedTestConfiguration
在测试类、其超类型层次结构或其包围类层次结构中不存在或元存在,那么将使用默认的包围配置继承模式。关于如何改变默认模式的细节,见下面的提示
:::tips 改变默认的封闭式配置继承模式
默认的封闭式配置继承模式是 INHERIT,但可以通过将 spring.test.enclosing.configuration JVM 系统属性设置为 OVERRIDE 来改变它。另
外,也可以通过 SpringProperties 机制来设置默认模式。
:::
Spring TestContext 框架对以下注解(都在 Spring 测试注解中有说到)尊重 @NestedTestConfiguration 语义:
- @BootstrapWith
- @ContextConfiguration
- @WebAppConfiguration
- @ContextHierarchy
- @ActiveProfiles
- @TestPropertySource
- @DynamicPropertySource
- @DirtiesContext
- @TestExecutionListeners
- @RecordApplicationEvents
- @Transactional
- @Commit
- @Rollback
- @Sql
- @SqlConfig
- @SqlMergeMode
- @TestConstructor
@EnabledIf
@EnabledIf
用于发出信号,说明被注解的 JUnit Jupiter 测试类或测试方法被启用,并且如果提供的表达式评估为 true,就应该运行。具体来说,如果表达式评估为 Boolean.TRUE 或一个等于 true 的字符串(忽略情况),则测试被启用。当应用于类级别时,该类中的所有测试方法默认也会自动启用。
表达式可以是以下的任何一种:
- Spring Expression Language(SpEL)表达式:比如说。
@EnabledIf("#{systemProperties['os.name'].toLowerCase().contains('mac')}")
- Spring 环境中可用属性的占位符。比如说。
@EnabledIf("${smoke.test.enabled}")
- 文本字面意义:例如。
@EnabledIf("true")
但是请注意,不是属性占位符的动态解析结果的文本字面意义为零,因为 @EnabledIf("false")
等同于 @Disabled
,而@EnabledIf("true")
在逻辑上毫无意义。
你可以使用 @EnabledIf
作为元注释来创建自定义的组合注释。例如,你可以创建一个自定义的 ·@EnabledOnMac· 注解,如下所示:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@EnabledIf(
expression = "#{systemProperties['os.name'].toLowerCase().contains('mac')}",
reason = "Enabled on Mac OS"
)
public @interface EnabledOnMac {}
@DisabledIf
和前面的 @EnabledIf 类似,不过这个是满足条件的话这不运行该测试方法。
下面是自定义注解的例子
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@DisabledIf(
expression = "#{systemProperties['os.name'].toLowerCase().contains('mac')}",
reason = "Disabled on Mac OS"
)
public @interface DisabledOnMac {}