Spring TestContext 框架
Spring TestContext框架(位于org.springframework.test.context包中)提供了通用的、基于注解的单元测试和集成测试支持,这种支持与所使用的测试框架无关。TestContext框架也非常重视“约定优于配置”的原则,提供了合理的默认设置,你可以通过基于注解的配置来覆盖这些默认值。
除了通用的测试基础设施之外,TestContext框架还明确支持JUnit Jupiter、JUnit 4和TestNG。对于JUnit 4和TestNG,Spring提供了抽象支持类。此外,Spring还为JUnit 4提供了自定义的JUnit Runner和自定义的JUnit Rules,以及为JUnit Jupiter提供的自定义Extension,这些工具允许你编写所谓的POJO测试类。POJO测试类不需要继承特定的类层次结构,例如那些抽象支持类。
部分总结
📄️ 关键抽象概念
该框架的核心由TestContextManager类以及TestContext、TestExecutionListener和SmartContextLoader接口组成。每个测试类都会创建一个TestContextManager(例如,在JUnit Jupiter中,用于执行单个测试类内的所有测试方法)。TestContextManager负责管理TestContext,后者保存当前测试的上下文。随着测试的进行,TestContextManager还会更新TestContext的状态,并将相关任务委托给TestExecutionListener的实现类,这些实现类通过提供依赖注入、管理事务等功能来实际执行测试。SmartContextLoader则负责为给定的测试类加载ApplicationContext。有关更多信息及各种实现的示例,请参阅Javadoc和Spring测试套件。
📄️ 自举TestContext框架
Spring TestContext框架的内部默认配置对于所有常见的使用场景来说已经足够了。然而,有时开发团队或第三方框架可能希望更改默认的ContextLoader,实现自定义的TestContext或ContextCache,扩展默认的ContextCustomizerFactory和TestExecutionListener实现等。为了对这些底层操作进行控制,Spring提供了一种启动策略(bootstrapping strategy)。
📄️ TestExecutionListener 配置
Spring 提供了以下默认注册的 TestExecutionListener 实现类,它们的注册顺序正好如下:
📄️ 应用事件
TestContext框架支持记录在ApplicationContext中发布的应用程序事件,以便在测试中对这些事件进行断言。在单个测试执行期间发布的所有事件都可以通过ApplicationEvents API获取,该API允许你将这些事件作为java.util.Stream进行处理。
📄️ 测试执行事件
EventPublishingTestExecutionListener提供了一种实现自定义TestExecutionListener的替代方法。测试的ApplicationContext中的组件可以监听EventPublishingTestExecutionListener发布的以下事件,每个事件都对应于TestExecutionListener API中的一个方法。
🗃️ 上下文管理
16 个项目
📄️ 测试夹具的依赖注入
当你使用DependencyInjectionTestExecutionListener(默认情况下是配置好的)时,你的测试实例的依赖项会从应用程序上下文中通过你使用@ContextConfiguration或相关注解配置的Bean中注入。你可以根据所选择的注解,以及这些注解是放在setter方法上还是字段上,来选择使用setter注入、字段注入,或者同时使用这两种方式。如果你使用的是JUnit Jupiter,还可以选择性地使用构造函数注入(详见“SpringExtension中的依赖注入”)。为了与Spring基于注解的注入支持保持一致,你也可以使用Spring的@Autowired注解,或者JSR-330标准中的@Inject注解来进行字段和setter注入。
📄️ 测试中的Bean覆盖
在测试中覆盖bean(Bean overriding in tests)指的是通过为测试类或其一个或多个非静态字段添加注解,来覆盖ApplicationContext中的特定bean的能力。
📄️ 测试请求范围(Request-scoped)和会话范围(Session-scoped)的bean
Spring从早期就开始支持请求作用域(request-scoped)和会话作用域(session-scoped)的Bean了,你可以通过以下步骤来测试这些作用域的Bean:
📄️ 交易管理
在TestContext框架中,事务由TransactionalTestExecutionListener管理,该监听器是默认配置好的,即使你没有在测试类上显式声明@TestExecutionListeners。然而,要支持事务功能,你必须在使用@ContextConfiguration语义加载的ApplicationContext中配置一个PlatformTransactionManager bean(更多细节稍后提供)。此外,你还必须在测试方法的类级别或方法级别上声明Spring的@Transactional注解。
📄️ 执行SQL脚本
在针对关系型数据库编写集成测试时,运行SQL脚本来修改数据库模式或向表中插入测试数据通常是很有帮助的。spring-jdbc模块提供了在加载SpringApplicationContext时执行SQL脚本来初始化嵌入式数据库或现有数据库的支持。详情请参阅“嵌入式数据库支持”以及“使用嵌入式数据库测试数据访问逻辑”。
📄️ 并行测试执行
Spring TestContext框架为在单个JVM内并行执行测试提供了基本支持。一般来说,这意味着大多数测试类或测试方法都可以在不修改测试代码或配置的情况下并行运行。
📄️ TestContext框架支持类
本节描述了在JUnit和TestNG中支持Spring TestContext框架的各种类。
📄️ 提前支持测试
本章介绍了Spring使用Spring TestContext框架对集成测试提供的“提前编译(AOT)”支持。