当与 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注解来指定一个配置类:

  1. @SpringJUnitConfig(TestConfig.class) // 指定配置类
  2. class ConfigurationClassJUnitJupiterSpringTests {
  3. // class body...
  4. }

更多细节请参见 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注解来指定一个配置类:

  1. @SpringJUnitWebConfig(TestConfig.class)
  2. class ConfigurationClassJUnitJupiterSpringWebTests {
  3. // class body...
  4. }

下面的例子显示了如何使用 @SpringJUnitWebConfig注解来指定一个配置文件的位置:

  1. @SpringJUnitWebConfig(locations = "/test-config.xml")
  2. class XmlJUnitJupiterSpringWebTests {
  3. // class body...
  4. }

更多细节请参见 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· 注解,如下所示:

  1. @Target({ElementType.TYPE, ElementType.METHOD})
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @EnabledIf(
  4. expression = "#{systemProperties['os.name'].toLowerCase().contains('mac')}",
  5. reason = "Enabled on Mac OS"
  6. )
  7. public @interface EnabledOnMac {}

@DisabledIf

和前面的 @EnabledIf 类似,不过这个是满足条件的话这不运行该测试方法。

下面是自定义注解的例子

  1. @Target({ElementType.TYPE, ElementType.METHOD})
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @DisabledIf(
  4. expression = "#{systemProperties['os.name'].toLowerCase().contains('mac')}",
  5. reason = "Disabled on Mac OS"
  6. )
  7. public @interface DisabledOnMac {}