Spring 5 中文解析核心篇-集成测试之TestContext(上)
Spring 框架(位于包中)提供了通用的、注解驱动的单元和集成测试支持,这些支持与所使用的测试框架无关。框架还非常重视约定优于配置,你可以通过基于注解的配置覆盖合理的默认值。
除了通用测试基础结构之外,框架还为JUnit 4,JUnit Jupiter(AKA JUnit 5)和TestNG提供了显式支持。对于JUnit 4和TestNG,Spring提供了抽象支持类。此外,Spring为JUnit 4提供了自定义JUnit Runner和自定义JUnit规则,以及JUnit Jupiter的自定义扩展,可让你编写所谓的POJO测试类。不需要POJO测试类来扩展特定的类层次结构,例如抽象支持类。下一节概述了框架的内部。如果你仅对使用框架感兴趣,而对使用自己的自定义监听器或自定义加载程序进行扩展不感兴趣,请直接转到配置( 、[依赖项注入](https://docs.spring.io/spring/docs/5.2.7.RELEASE/spring-framework-reference/testing.html#testcontext-fixture-di)、[事务管理](https://docs.spring.io/spring/docs/5.2.7.RELEASE/spring-framework-reference/testing.html#testcontext-tx)、[支持类](https://docs.spring.io/spring/docs/5.2.7.RELEASE/spring-framework-reference/testing.html#testcontext-support-classes)和[注解支持](https://docs.spring.io/spring/docs/5.2.7.RELEASE/spring-framework-reference/testing.html#integration-testing-annotations)部分。
###### 3.5.1 关键抽象
该框架的核心由类和,和接口组成。为每个测试类创建一个(例如,用于在JUnit Jupiter中的单个测试类中执行所有测试方法)。反过来,管理包含当前测试上下文的。随着测试的进行,还更新了的状态,并委托给实现,该实现通过提供依赖项注入,管理事务等来检测实际的测试执行。负责为给定的测试类加载。有关更多信息和各种实现的示例,请参见和Spring测试套件。
TestContext
封装了在其中执行测试的上下文(与使用中的实际测试框架无关),并为其负责的测试实例提供了上下文管理和缓存支持。如果需要,还委托给来加载。
TestContextManager
是Spring 框架的主要入口点,并负责管理单个并在定义良好的测试执行点向每个注册的发出事件信号:
在任何类之前或在特定测试框架的所有方法之前。
测试实例后处理。
在任何或在每个特定测试框架的方法之前。
在执行测试方法之前但在测试设置之后。
在测试方法执行之后,但在测试拆卸之前。
之后的任何方法或之后的每一个特定的测试框架。
在特定测试框架的任何类后或所有方法之后。
TestExecutionListener
定义用于对由注册监听器的发布的测试执行事件做出反应的API。请参阅配置。
上下文加载器
是一个策略接口,用于为Spring 框架管理的集成测试加载。你应该实现而不是此接口,以提供对组件类,激活的bean定义配置文件、测试属性源、上下文层次结构和支持的支持。
是接口的扩展,它取代了原始的最小 SPI。具体来说,可以选择处理资源位置、组件类或上下文初始化器。此外,可以在其加载的上下文中设置激活Bean定义配置文件并测试属性源。
Spring提供了以下实现:
: 它是两个默认加载器之一,它在内部委派给、或,具体取决于为测试类声明的配置或默认位置或默认配置类的存在。仅当Groovy在类路径上时才启用Groovy支持。
: 它是两个默认加载器之一,它在内部委派给、GenericXmlWebContextLoader或,具体取决于为测试类声明的配置或默认位置或默认配置类的存在。仅当测试类上存在时,才使用Web 。仅当Groovy在类路径上时才启用Groovy支持。
:从组件类加载标准。
: 从组件类加载。
: 从Groovy脚本或XML配置文件的资源位置加载标准。
: 从Groovy脚本或XML配置文件的资源位置加载。
: 从XML资源位置加载标准。
: 从XML资源位置加载。
:从Java属性文件加载标准。
###### 3.5.2 引导TestContext框架
Spring 框架内部的默认配置足以满足所有常见用例。但是,有时开发团队或第三方框架希望更改默认的,实现自定义的或,扩展默认的和实现等等。为了对框架的运行方式进行低级别控制,Spring提供了引导策略。
定义了用于引导框架的SPI。使用加载当前测试的实现并构建它管理的。你可以直接使用或作为元注解,为测试类(或测试类层次结构)配置自定义引导策略。如果没有通过使用显式配置引导程序,则根据的存在,使用或。
由于 SPI将来可能会更改(以适应新的需求),我们强烈建议实现者不要直接实现此接口,而应扩展或其具体子类之一。
###### 3.5.3 配置
Spring提供了以下实现,这些实现默认情况下按以下顺序注册:
:为配置Servlet API模拟。
:处理模式的注解。
: 为测试实例提供依赖项注入。
: 处理模式的注解。
: 提供具有默认回滚语义的事务测试执行。
: 运行使用注释配置的SQL脚本。
**注册实现**
你可以使用注解为测试类及其子类注解实现。有关详细信息和示例,请参见和[@TestExecutionListeners](https://docs.spring.io/spring-framework/docs/5.2.7.RELEASE/javadoc-api/org/springframework/test/context/TestExecutionListeners.html)的javadoc。
默认TestExecutionListener实现自动发现
通过使用注册实现适用于有限测试方案中使用的自定义监听器。但是,如果需要在整个测试套件中使用自定义监听器,则会变得很麻烦。通过机制支持自动发现默认的实现,可以解决这个问题。
具体来说,模块在其属性文件中的为下声明所有核心默认实现。第三方框架和开发人员可以通过自己的属性文件以相同的方式将自己的实现贡献到默认监听器列表中。
TestExecutionListener顺序实现
当框架通过上述机制发现默认实现时,实例化的监听器将使用Spring的进行排序,该类将使用Spring的接口和@Order注解进行排序。Spring提供的和所有默认的实现以适当的值实现。因此,第三方框架和开发人员应通过实施或声明来确保按默认顺序注册其默认的实现。请参阅javadoc以获取核心默认实现的方法,以获取有关为每个核心监听器分配哪些值的详细信息。
TestExecutionListener合并实现
如果通过注册了自定义,则不会注册默认监听器。在大多数常见的测试方案中,这有效地迫使开发人员手动声明除任何自定义监听器之外的所有默认监听器。
下面的清单演示了这种配置样式:
@ContextConfiguration
@TestExecutionListeners({
MyCustomTestExecutionListener.class,
ServletTestExecutionListener.class,
DirtiesContextBeforeModesTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
SqlScriptsTestExecutionListener.class
})
class MyTest {
// class body...
}
这种方法的挑战在于,它要求开发人员确切地知道默认情况下注册了哪些监听器。此外,默认的监听器集可以随版本的不同而变化-例如,在Spring框架4.1中引入了,在Spring框架4.2中引入了。此外,诸如Spring Boot和Spring Security之类的第三方框架通过使用上述注册了自己的默认实现。
为避免必须了解并重新声明所有默认监听器,可以将的属性设置为。表示应将本地声明的监听器与默认监听器合并。合并算法可确保从列表中删除重复项,并确保根据的语义对合并后的监听器集进行排序,如实现中所述。如果监听器实现或使用进行注解,则它可以影响将其与默认值合并的位置。否则,合并时,本地声明的监听器将追加到默认侦听器列表中。
例如,如果上一个示例中的类将顺序值(例如500)配置为小于的顺序(恰好是1000),则可以自动与默认列表合并。在前面,并且前面的示例可以替换为以下示例:
@ContextConfiguration
@TestExecutionListeners(
listeners = MyCustomTestExecutionListener.class,
mergeMode = MERGE_WITH_DEFAULTS
)
class MyTest {
// class body...
}
###### 3.5.4 测试执行事件
Spring框架5.2中引入的提供了一种实现自定义的替代方法。测试的中的组件可以监听发布的以下事件,每个事件都与 API中的方法相对应。
只有当已经加载时,才会发布这些事件。
这些事件可能由于各种原因被使用,例如重置模拟bean或跟踪测试执行。使用测试执行事件而不是实现自定义的一个优势是,测试执行事件可以由在测试中注册的任何Spring bean所使用,并且此类bean可以直接受益于依赖项注入和的其他功能。相反,在中不是bean。
为了监听测试执行事件,Spring Bean可以选择实现接口。或者,可以使用注解监听器方法,并将监听方法配置为监听上面列出的特定事件类型之一(请参阅基于注解的事件监听器)。由于这种方法的流行,Spring提供了以下专用的注解,以简化测试执行事件监听器的注册。这些注解驻留在包中。
参考代码:
异常处理
默认情况下,如果测试执行事件监听器在使用事件时抛出异常,则该异常将传播到使用中的基础测试框架(例如JUnit或TestNG)。例如,如果使用导致异常,则相应的测试方法将因异常而失败。相反,如果异步测试执行事件监听器引发异常,则该异常不会传播到基础测试框架。有关异步异常处理的更多详细信息,请查阅类级javadoc。
异步监听器
如果你希望特定的测试执行事件监听器异步处理事件,你可以使用Spring的常规支持。有关更多详细信息,请查阅的类级javadoc。
参考代码:
作者
个人从事金融行业,就职过易极付、思建科技、某网约车平台等重庆一流技术团队,目前就职于某银行负责统一支付系统建设。自身对金融行业有强烈的爱好。同时也实践大数据、数据存储、自动化集成和部署、分布式微服务、响应式编程、人工智能等领域。同时也热衷于技术分享创立公众号和博客站点对知识体系进行分享。关注公众号:青年IT男 获取最新技术文章推送!
博客地址: http://youngitman.tech
CSDN: https://blog.csdn.net/liyong1028826685
微信公众号:

技术交流群:
