TestContext 框架支持类
本节描述了支持 Infra TestContext 框架的各种类。
Infra JUnit 4 运行器
Infra TestContext 框架通过自定义运行器(在 JUnit 4.12 或更高版本上受支持)提供了与 JUnit 4 的完全集成。
通过使用 @RunWith(InfraJUnit4ClassRunner.class) 或更短的 @RunWith(InfraRunner.class) 变体注解测试类,开发人员可以实现基于标准 JUnit 4 的单元测试和集成测试,同时获得 TestContext 框架的好处,例如支持加载应用程序上下文、测试实例的依赖注入、事务性测试方法执行等。
如果您想将 Infra TestContext 框架与其他运行器(例如 JUnit 4 的 Parameterized 运行器)或第三方运行器(例如 MockitoJUnitRunner)一起使用,您可以选择使用 Infra 对 JUnit 规则的支持 代替。
以下代码清单显示了配置测试类以使用自定义 Infra Runner 运行的最低要求:
-
Java
@RunWith(InfraRunner.class)
@TestExecutionListeners({})
public class SimpleTest {
@Test
public void testMethod() {
// 测试逻辑...
}
}
在前面的示例中,@TestExecutionListeners 配置为空列表,以禁用默认监听器,否则这些监听器将需要通过 @ContextConfiguration 配置 ApplicationContext。
Infra JUnit 4 规则
infra.test.context.junit4.rules 包提供了以下 JUnit 4 规则(在 JUnit 4.12 或更高版本上受支持):
-
InfraClassRule -
InfraMethodRule
InfraClassRule 是一个 JUnit TestRule,支持 Infra TestContext 框架的类级功能,而 InfraMethodRule 是一个 JUnit MethodRule,支持 Infra TestContext 框架的实例级和方法级功能。
与 InfraRunner 相比,基于 Infra 规则的 JUnit 支持具有独立于任何 org.junit.runner.Runner 实现的优势,因此可以与现有的替代运行器(如 JUnit 4 的 Parameterized)或第三方运行器(如 MockitoJUnitRunner)结合使用。
为了支持 TestContext 框架的完整功能,必须将 InfraClassRule 与 InfraMethodRule 结合使用。
以下示例显示了在集成测试中声明这些规则的正确方法:
-
Java
// 可选地通过 @RunWith(...) 指定非 Infra 运行器
@ContextConfiguration
public class IntegrationTest {
@ClassRule
public static final InfraClassRule springClassRule = new InfraClassRule();
@Rule
public final InfraMethodRule springMethodRule = new InfraMethodRule();
@Test
public void testMethod() {
// 测试逻辑...
}
}
JUnit 4 支持类
infra.test.context.junit4 包为基于 JUnit 4 的测试用例(在 JUnit 4.12 或更高版本上受支持)提供了以下支持类:
-
AbstractJUnit4InfraContextTests -
AbstractTransactionalJUnit4InfraContextTests
AbstractJUnit4InfraContextTests 是一个抽象基础测试类,它将 Infra TestContext 框架与 JUnit 4 环境中的显式 ApplicationContext 测试支持集成在一起。
当您扩展 AbstractJUnit4InfraContextTests 时,您可以访问一个 protected applicationContext 实例变量,您可以使用它来执行显式 Bean 查找或测试整个上下文的状态。
AbstractTransactionalJUnit4InfraContextTests 是 AbstractJUnit4InfraContextTests 的抽象事务扩展,它为 JDBC 访问添加了一些便利功能。
此类期望在 ApplicationContext 中定义一个 javax.sql.DataSource Bean 和一个 PlatformTransactionManager Bean。
当您扩展 AbstractTransactionalJUnit4InfraContextTests 时,您可以访问一个 protected jdbcTemplate 实例变量,您可以使用它来运行 SQL 语句以查询数据库。
您可以使用此类查询在运行数据库相关应用程序代码之前和之后确认数据库状态,并且 Infra 确保此类查询在与应用程序代码相同的事务范围内运行。
当与 ORM 工具结合使用时,请务必避免 误报。
如 JDBC 测试支持 中所述,AbstractTransactionalJUnit4InfraContextTests 还提供了便利方法,这些方法使用上述 jdbcTemplate 委托给 JdbcTestUtils 中的方法。
此外,AbstractTransactionalJUnit4InfraContextTests 提供了一个 executeSqlScript(..) 方法,用于针对配置的 DataSource 运行 SQL 脚本。
这些类是为了方便扩展而提供的。
如果您不希望您的测试类绑定到特定于 Infra 的类层次结构,您可以使用 @RunWith(InfraRunner.class) 或 Infra JUnit 规则 配置自己的自定义测试类。
|
JUnit Jupiter 的 InfraExtension
Infra TestContext 框架提供了与 JUnit 5 中引入的 JUnit Jupiter 测试框架的完全集成。
通过使用 @ExtendWith(InfraExtension.class) 注解测试类,您可以实现基于标准 JUnit Jupiter 的单元测试和集成测试,同时获得 TestContext 框架的好处,例如支持加载应用程序上下文、测试实例的依赖注入、事务性测试方法执行等。
此外,由于 JUnit Jupiter 中丰富的扩展 API,Infra 提供了以下功能,超越了 Infra 为 JUnit 4 和 TestNG 支持的功能集:
-
测试构造函数、测试方法和测试生命周期回调方法的依赖注入。 有关更多详细信息,请参阅 使用
InfraExtension的依赖注入。 -
基于 SpEL 表达式、环境变量、系统属性等强大的 条件测试执行 支持。 有关更多详细信息和示例,请参阅 Infra JUnit Jupiter 测试注解 中的
@EnabledIf和@DisabledIf文档。 -
结合了 Infra 和 JUnit Jupiter 注解的自定义组合注解。 有关更多详细信息,请参阅 测试的元注解支持 中的
@TransactionalDevTestConfig和@TransactionalIntegrationTest示例。
以下代码清单显示了如何配置测试类以将 InfraExtension 与 @ContextConfiguration 结合使用:
-
Java
// 指示 JUnit Jupiter 使用 Infra 支持扩展测试。
@ExtendWith(InfraExtension.class)
// 指示 Infra 从 TestConfig.class 加载 ApplicationContext
@ContextConfiguration(classes = TestConfig.class)
class SimpleTests {
@Test
void testMethod() {
// 测试逻辑...
}
}
由于您也可以在 JUnit 5 中将注解用作元注解,Infra 提供了 @JUnitConfig 和 @JUnitWebConfig 组合注解,以简化测试 ApplicationContext 和 JUnit Jupiter 的配置。
以下示例使用 @JUnitConfig 减少了上一个示例中使用的配置量:
-
Java
// 指示 Infra 向 JUnit Jupiter 注册 InfraExtension
// 并从 TestConfig.class 加载 ApplicationContext
@JUnitConfig(TestConfig.class)
class SimpleTests {
@Test
void testMethod() {
// 测试逻辑...
}
}
同样,以下示例使用 @JUnitWebConfig 创建用于 JUnit Jupiter 的 WebApplicationContext:
-
Java
// 指示 Infra 向 JUnit Jupiter 注册 InfraExtension
// 并从 TestWebConfig.class 加载 WebApplicationContext
@JUnitWebConfig(TestWebConfig.class)
class SimpleWebTests {
@Test
void testMethod() {
// 测试逻辑...
}
}
有关更多详细信息,请参阅 Infra JUnit Jupiter 测试注解 中的 @JUnitConfig 和 @JUnitWebConfig 文档。
使用 InfraExtension 的依赖注入
InfraExtension 实现了 JUnit Jupiter 的 ParameterResolver 扩展 API,这使得 Infra 能够为测试构造函数、测试方法和测试生命周期回调方法提供依赖注入。
具体来说,InfraExtension 可以将测试的 ApplicationContext 中的依赖项注入到使用 Infra @BeforeTransaction 和 @AfterTransaction 或 JUnit 的 @BeforeAll、@AfterAll、@BeforeEach、@AfterEach、@Test、@RepeatedTest、@ParameterizedTest 等注解的测试构造函数和方法中。
构造函数注入
如果 JUnit Jupiter 测试类的构造函数中的特定参数类型为 ApplicationContext(或其子类型),或者使用 @Autowired、@Qualifier 或 @Value 进行了注解或元注解,Infra 将使用测试的 ApplicationContext 中的相应 Bean 或值注入该特定参数。
如果测试类构造函数被认为是 可自动装配的 (autowirable),Infra 也可以配置为自动装配该构造函数的所有参数。 如果满足以下条件之一(按优先顺序),则构造函数被认为是可自动装配的。
-
构造函数使用
@Autowired进行了注解。 -
测试类上存在
@TestConstructor或元存在,并且autowireMode属性设置为ALL。 -
默认的 测试构造函数自动装配模式 已更改为
ALL。
有关使用 @TestConstructor 以及如何更改全局 测试构造函数自动装配模式 的详细信息,请参阅 @TestConstructor。
如果测试类的构造函数被认为是 可自动装配的,Infra 将承担解析构造函数中所有参数的责任。
因此,向 JUnit Jupiter 注册的其他 ParameterResolver 都无法解析此类构造函数的参数。
|
|
如果使用 原因是 要将具有 "before test method" 或 "after test method" 模式的 |
在以下示例中,Infra 将从 TestConfig.class 加载的 ApplicationContext 中的 OrderService Bean 注入到 OrderServiceIntegrationTests 构造函数中。
-
Java
@JUnitConfig(TestConfig.class)
class OrderServiceIntegrationTests {
private final OrderService orderService;
@Autowired
OrderServiceIntegrationTests(OrderService orderService) {
this.orderService = orderService;
}
// 使用注入的 OrderService 的测试
}
请注意,此功能允许测试依赖项为 final,因此是不可变的。
如果 infra.test.constructor.autowire.mode 属性设置为 all(请参阅 @TestConstructor),我们可以省略上一个示例中构造函数上的 @Autowired 声明,结果如下。
-
Java
@JUnitConfig(TestConfig.class)
class OrderServiceIntegrationTests {
private final OrderService orderService;
OrderServiceIntegrationTests(OrderService orderService) {
this.orderService = orderService;
}
// 使用注入的 OrderService 的测试
}
方法注入
如果 JUnit Jupiter 测试方法或测试生命周期回调方法中的参数类型为 ApplicationContext(或其子类型),或者使用 @Autowired、@Qualifier 或 @Value 进行了注解或元注解,Infra 将使用测试的 ApplicationContext 中的相应 Bean 注入该特定参数的值。
在以下示例中,Infra 将从 TestConfig.class 加载的 ApplicationContext 中的 OrderService 注入到 deleteOrder() 测试方法中:
-
Java
@JUnitConfig(TestConfig.class)
class OrderServiceIntegrationTests {
@Test
void deleteOrder(@Autowired OrderService orderService) {
// 使用测试 ApplicationContext 中的 orderService
}
}
由于 JUnit Jupiter 中 ParameterResolver 支持的健壮性,您还可以将多个依赖项注入到单个方法中,不仅来自 Infra,还来自 JUnit Jupiter 本身或其他第三方扩展。
以下示例显示了如何让 Infra 和 JUnit Jupiter 同时将依赖项注入到 placeOrderRepeatedly() 测试方法中。
-
Java
@JUnitConfig(TestConfig.class)
class OrderServiceIntegrationTests {
@RepeatedTest(10)
void placeOrderRepeatedly(RepetitionInfo repetitionInfo,
@Autowired OrderService orderService) {
// 使用测试 ApplicationContext 中的 orderService
// 和来自 JUnit Jupiter 的 repetitionInfo
}
}
请注意,使用 JUnit Jupiter 中的 @RepeatedTest 可以让测试方法获得对 RepetitionInfo 的访问权限。
@Nested 测试类配置
自 TODAY Framework 5.0 起,Infra TestContext 框架 支持在 JUnit Jupiter 中的 @Nested 测试类上使用测试相关注解;然而,在 Infra Framework 5.3 之前,类级测试配置注解不会像从超类那样从封闭类 继承。
TODAY Framework 5.3 引入了对从封闭类继承测试类配置的一流支持,默认情况下将继承此类配置。
要将默认的 INHERIT 模式更改为 OVERRIDE 模式,您可以使用 @NestedTestConfiguration(EnclosingConfiguration.OVERRIDE) 注解单个 @Nested 测试类。
显式 @NestedTestConfiguration 声明将应用于带注解的测试类及其任何子类和嵌套类。
因此,您可以使用 @NestedTestConfiguration 注解顶级测试类,这将递归应用于其所有嵌套测试类。
为了允许开发团队将默认值更改为 OVERRIDE——例如,为了与 TODAY Framework 5.0 到 5.2 兼容——可以通过 JVM 系统属性或类路径根目录下的 spring.properties 文件全局更改默认模式。
有关详细信息,请参阅 "更改默认封闭配置继承模式" 说明。
虽然下面的 "Hello World" 示例非常简单,但它显示了如何在顶级类上声明由其 @Nested 测试类继承的通用配置。
在这个特定示例中,仅继承了 TestConfig 配置类。
每个嵌套测试类都提供了自己的一组活动配置文件,从而为每个嵌套测试类产生一个不同的 ApplicationContext(有关详细信息,请参阅 上下文缓存)。
请查阅 支持的注解 列表,以查看哪些注解可以在 @Nested 测试类中继承。
-
Java
@JUnitConfig(TestConfig.class)
class GreetingServiceTests {
@Nested
@ActiveProfiles("lang_en")
class EnglishGreetings {
@Test
void hello(@Autowired GreetingService service) {
assertThat(service.greetWorld()).isEqualTo("Hello World");
}
}
@Nested
@ActiveProfiles("lang_de")
class GermanGreetings {
@Test
void hello(@Autowired GreetingService service) {
assertThat(service.greetWorld()).isEqualTo("Hallo Welt");
}
}
}
TestNG 支持类
infra.test.context.testng 包为基于 TestNG 的测试用例提供了以下支持类:
-
AbstractTestNGInfraContextTests -
AbstractTransactionalTestNGInfraContextTests
AbstractTestNGInfraContextTests 是一个抽象基础测试类,它将 Infra TestContext 框架与 TestNG 环境中的显式 ApplicationContext 测试支持集成在一起。
当您扩展 AbstractTestNGInfraContextTests 时,您可以访问一个 protected applicationContext 实例变量,您可以使用它来执行显式 Bean 查找或测试整个上下文的状态。
AbstractTransactionalTestNGInfraContextTests 是 AbstractTestNGInfraContextTests 的抽象事务扩展,它为 JDBC 访问添加了一些便利功能。
此类期望在 ApplicationContext 中定义一个 javax.sql.DataSource Bean 和一个 PlatformTransactionManager Bean。
当您扩展 AbstractTransactionalTestNGInfraContextTests 时,您可以访问一个 protected jdbcTemplate 实例变量,您可以使用它来运行 SQL 语句以查询数据库。
您可以使用此类查询在运行数据库相关应用程序代码之前和之后确认数据库状态,并且 Infra 确保此类查询在与应用程序代码相同的事务范围内运行。
当与 ORM 工具结合使用时,请务必避免 误报。
如 JDBC 测试支持 中所述,AbstractTransactionalTestNGInfraContextTests 还提供了便利方法,这些方法使用上述 jdbcTemplate 委托给 JdbcTestUtils 中的方法。
此外,AbstractTransactionalTestNGInfraContextTests 提供了一个 executeSqlScript(..) 方法,用于针对配置的 DataSource 运行 SQL 脚本。
这些类是为了方便扩展而提供的。
如果您不希望您的测试类绑定到特定于 Infra 的类层次结构,您可以使用 @ContextConfiguration、@TestExecutionListeners 等配置自己的自定义测试类,并使用 TestContextManager 手动检测您的测试类。
请参阅 AbstractTestNGInfraContextTests 的源代码,以获取有关如何检测测试类的示例。
|