Spring TestContext
框架(位于org.springframework.test.context
包中)提供了通用的、注解驱动的单元和集成测试反对,这些反对与所应用的测试框架无关。TestContext
框架还非常重视约定优于配置,你能够通过基于注解的配置笼罩正当的默认值。
除了通用测试根底构造之外,TestContext
框架还为JUnit 4,JUnit Jupiter(AKA JUnit 5)和TestNG提供了显式反对。对于JUnit 4和TestNG,Spring提供了形象反对类。此外,Spring为JUnit 4提供了自定义JUnit Runner和自定义JUnit规定,以及JUnit Jupiter的自定义扩大,可让你编写所谓的POJO测试类。不须要POJO测试类来扩大特定的类层次结构,例如形象反对类。下一节概述了TestContext
框架的外部。如果你仅对应用框架感兴趣,而对应用本人的自定义监听器或自定义加载程序进行扩大不感兴趣,请间接转到配置(上下文治理 、依赖项注入、事务管理、反对类和注解反对局部。
3.5.1 要害形象
该框架的外围由TestContextManager
类和TestContext
,TestExecutionListener
和SmartContextLoader
接口组成。为每个测试类创立一个TestContextManager
(例如,用于在JUnit Jupiter中的单个测试类中执行所有测试方法)。反过来,TestContextManager
治理蕴含以后测试上下文的TestContext
。随着测试的进行,TestContextManager
还更新了TestContext
的状态,并委托给TestExecutionListener
实现,该实现通过提供依赖项注入,治理事务等来检测理论的测试执行。SmartContextLoader
负责为给定的测试类加载ApplicationContext
。无关更多信息和各种实现的示例,请参见javadoc和Spring测试套件。
TestContext
TestContext
封装了在其中执行测试的上下文(与应用中的理论测试框架无关),并为其负责的测试实例提供了上下文治理和缓存反对。如果须要,TestContext
还委托给SmartContextLoader
来加载ApplicationContext
。
TestContextManager
TestContextManager
是Spring TestContext
框架的次要入口点,并负责管理单个TestContext
并在定义良好的测试执行点向每个注册的TestExecutionListener
收回事件信号:
- 在任何
before
类之前或在特定测试框架的所有办法之前。 - 测试实例后处理。
- 在任何
before
或在每个特定测试框架的办法之前。 - 在执行测试方法之前但在测试设置之后。
- 在测试方法执行之后,但在测试装配之前。
- 之后的任何办法或之后的每一个特定的测试框架。
- 在特定测试框架的任何类后或所有办法之后。
TestExecutionListener
TestExecutionListener
定义用于对由注册监听器的TestContextManager
公布的测试执行事件做出反馈的API。请参阅TestExecutionListener配置。
上下文加载器
ContextLoader
是一个策略接口,用于为Spring TestContext
框架治理的集成测试加载ApplicationContext
。你应该实现SmartContextLoader
而不是此接口,以提供对组件类,激活的bean定义配置文件、测试属性源、上下文层次结构和WebApplicationContext
反对的反对。
SmartContextLoader
是ContextLoader
接口的扩大,它取代了原始的最小ContextLoader
SPI。具体来说,SmartContextLoader
能够抉择解决资源地位、组件类或上下文初始化器。此外,SmartContextLoader
能够在其加载的上下文中设置激活Bean定义配置文件并测试属性源。
Spring提供了以下实现:
DelegatingSmartContextLoader
: 它是两个默认加载器之一,它在外部委派给AnnotationConfigContextLoader
、GenericXmlContextLoader
或GenericGroovyXmlContextLoader
,具体取决于为测试类申明的配置或默认地位或默认配置类的存在。仅当Groovy在类门路上时才启用Groovy反对。WebDelegatingSmartContextLoader
: 它是两个默认加载器之一,它在外部委派给AnnotationConfigWebContextLoader
、GenericXmlWebContextLoader或GenericGroovyXmlWebContextLoader
,具体取决于为测试类申明的配置或默认地位或默认配置类的存在。仅当测试类上存在@WebAppConfiguration
时,才应用WebContextLoader
。仅当Groovy在类门路上时才启用Groovy反对。AnnotationConfigContextLoader
:从组件类加载规范ApplicationContext
。AnnotationConfigWebContextLoader
: 从组件类加载WebApplicationContext
。GenericGroovyXmlContextLoader
: 从Groovy脚本或XML配置文件的资源地位加载规范ApplicationContext
。GenericGroovyXmlWebContextLoader
: 从Groovy脚本或XML配置文件的资源地位加载WebApplicationContext
。GenericXmlContextLoader
: 从XML资源地位加载规范ApplicationContext
。GenericXmlWebContextLoader
: 从XML资源地位加载WebApplicationContext
。GenericPropertiesContextLoader
:从Java属性文件加载规范ApplicationContext
。
3.5.2 疏导TestContext框架
Spring TestContext
框架外部的默认配置足以满足所有常见用例。然而,有时开发团队或第三方框架心愿更改默认的ContextLoader
,实现自定义的TestContext
或ContextCache
,扩大默认的ContextCustomizerFactory
和TestExecutionListener
实现等等。为了对TestContext
框架的运行形式进行低级别管制,Spring提供了疏导策略。
TestContextBootstrapper
定义了用于疏导TestContext
框架的SPI。TestContextManager
应用TestContextBootstrapper
加载以后测试的TestExecutionListener
实现并构建它治理的TestContext
。你能够间接应用@BootstrapWith
或作为元注解,为测试类(或测试类层次结构)配置自定义疏导策略。如果没有通过应用@BootstrapWith
显式配置疏导程序,则依据@WebAppConfiguration
的存在,应用DefaultTestContextBootstrapper
或WebTestContextBootstrapper
。
因为TestContextBootstrapper
SPI未来可能会更改(以适应新的需要),咱们强烈建议实现者不要间接实现此接口,而应扩大AbstractTestContextBootstrapper
或其具体子类之一。
3.5.3 TestExecutionListener
配置
Spring提供了以下TestExecutionListener
实现,这些实现默认状况下按以下程序注册:
ServletTestExecutionListener
:为WebApplicationContext
配置Servlet API模仿。DirtiesContextBeforeModesTestExecutionListener
:解决before
模式的@DirtiesContext
注解。DependencyInjectionTestExecutionListener
: 为测试实例提供依赖项注入。DirtiesContextTestExecutionListener
: 解决after
模式的@DirtiesContext
注解。TransactionalTestExecutionListener
: 提供具备默认回滚语义的事务测试执行。SqlScriptsTestExecutionListener
: 运行应用@Sql
正文配置的SQL脚本。EventPublishingTestExecutionListener
: 将测试执行事件公布到测试的ApplicationContext
中(请参阅测试执行事件)。
注册TestExecutionListener
实现
你能够应用@TestExecutionListeners
注解为测试类及其子类注解TestExecutionListener
实现。无关详细信息和示例,请参见注解反对和@TestExecutionListeners的javadoc。
默认TestExecutionListener实现主动发现
通过应用@TestExecutionListeners
注册TestExecutionListener
实现实用于无限测试计划中应用的自定义监听器。然而,如果须要在整个测试套件中应用自定义监听器,则会变得很麻烦。通过SpringFactoriesLoader
机制反对主动发现默认的TestExecutionListener
实现,能够解决这个问题。
具体来说,spring-test
模块在其META-INF/spring.factories
属性文件中的key
为org.springframework.test.context.TestExecutionListener
下申明所有外围默认TestExecutionListener
实现。第三方框架和开发人员能够通过本人的META-INF/spring.factories
属性文件以雷同的形式将本人的TestExecutionListener
实现奉献到默认监听器列表中。
TestExecutionListener程序实现
当TestContext
框架通过上述SpringFactoriesLoader
机制发现默认TestExecutionListener
实现时,实例化的监听器将应用Spring的AnnotationAwareOrderComparator
进行排序,该类将应用Spring的Ordered
接口和@Order注解进行排序。Spring提供的AbstractTestExecutionListener
和所有默认的TestExecutionListener
实现以适当的值实现Ordered
。因而,第三方框架和开发人员应通过施行Ordered
或申明@Order
来确保按默认程序注册其默认的TestExecutionListener
实现。请参阅javadoc以获取外围默认TestExecutionListener
实现的getOrder()
办法,以获取无关为每个外围监听器调配哪些值的详细信息。
TestExecutionListener合并实现
如果通过@TestExecutionListeners
注册了自定义TestExecutionListener
,则不会注册默认监听器。在大多数常见的测试计划中,这无效地迫使开发人员手动申明除任何自定义监听器之外的所有默认监听器。
上面的清单演示了这种配置款式:
@ContextConfiguration@TestExecutionListeners({ MyCustomTestExecutionListener.class, ServletTestExecutionListener.class, DirtiesContextBeforeModesTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class, SqlScriptsTestExecutionListener.class})class MyTest { // class body...}
这种办法的挑战在于,它要求开发人员确切地晓得默认状况下注册了哪些监听器。此外,默认的监听器集能够随版本的不同而变动-例如,在Spring框架4.1中引入了SqlScriptsTestExecutionListener
,在Spring框架4.2中引入了DirtiesContextBeforeModesTestExecutionListener
。此外,诸如Spring Boot和Spring Security之类的第三方框架通过应用上述主动发现机制注册了本人的默认TestExecutionListener
实现。
为防止必须理解并从新申明所有默认监听器,能够将@TestExecutionListeners
的mergeMode
属性设置为MergeMode.MERGE_WITH_DEFAULTS
。MERGE_WITH_DEFAULTS
示意应将本地申明的监听器与默认监听器合并。合并算法可确保从列表中删除反复项,并确保依据AnnotationAwareOrderComparator
的语义对合并后的监听器集进行排序,如Ordering TestExecutionListener实现中所述。如果监听器实现Ordered
或应用@Order
进行注解,则它能够影响将其与默认值合并的地位。否则,合并时,本地申明的监听器将追加到默认侦听器列表中。
例如,如果上一个示例中的MyCustomTestExecutionListener
类将程序值(例如500)配置为小于ServletTestExecutionListener
的程序(恰好是1000),则MyCustomTestExecutionListener
能够主动与默认列表合并。在ServletTestExecutionListener
后面,并且后面的示例能够替换为以下示例:
@ContextConfiguration@TestExecutionListeners( listeners = MyCustomTestExecutionListener.class, mergeMode = MERGE_WITH_DEFAULTS)class MyTest { // class body...}
3.5.4 测试执行事件
Spring框架5.2中引入的EventPublishingTestExecutionListener
提供了一种实现自定义TestExecutionListener
的代替办法。测试的ApplicationContext
中的组件能够监听EventPublishingTestExecutionListener
公布的以下事件,每个事件都与TestExecutionListener
API中的办法绝对应。
BeforeTestClassEvent
PrepareTestInstanceEvent
BeforeTestMethodEvent
BeforeTestExecutionEvent
AfterTestExecutionEvent
AfterTestMethodEvent
AfterTestClassEvent
只有当ApplicationContext
曾经加载时,才会公布这些事件。
这些事件可能因为各种起因被应用,例如重置模仿bean或跟踪测试执行。应用测试执行事件而不是实现自定义TestExecutionListener
的一个劣势是,测试执行事件能够由在测试ApplicationContext
中注册的任何Spring bean所应用,并且此类bean能够间接受害于依赖项注入和ApplicationContext
的其余性能。相同,TestExecutionListener
在ApplicationContext
中不是bean。
为了监听测试执行事件,Spring Bean能够抉择实现org.springframework.context.ApplicationListener
接口。或者,能够应用@EventListener
注解监听器办法,并将监听办法配置为监听下面列出的特定事件类型之一(请参阅基于注解的事件监听器)。因为这种办法的风行,Spring提供了以下专用的@EventListener
注解,以简化测试执行事件监听器的注册。这些注解驻留在org.springframework.test.context.event.annotation
包中。
@BeforeTestClass
@PrepareTestInstance
@BeforeTestMethod
@BeforeTestExecution
@AfterTestExecution
@AfterTestMethod
@AfterTestClass
参考代码:org.liyong.test.annotation.test.spring.TestExecutionEventTest
异样解决
默认状况下,如果测试执行事件监听器在应用事件时抛出异样,则该异样将流传到应用中的根底测试框架(例如JUnit或TestNG)。例如,如果应用BeforeTestMethodEvent
导致异样,则相应的测试方法将因异样而失败。相同,如果异步测试执行事件监听器引发异样,则该异样不会流传到根底测试框架。无关异步异样解决的更多详细信息,请查阅@EventListener
类级javadoc。
异步监听器
如果你心愿特定的测试执行事件监听器异步处理事件,你能够应用Spring的惯例@Async反对。无关更多详细信息,请查阅@EventListener
的类级javadoc。
参考代码:org.liyong.test.annotation.test.spring.TestExecutionEventTest
作者
集体从事金融行业,就任过易极付、思建科技、某网约车平台等重庆一流技术团队,目前就任于某银行负责对立领取零碎建设。本身对金融行业有强烈的喜好。同时也实际大数据、数据存储、自动化集成和部署、散布式微服务、响应式编程、人工智能等畛域。同时也热衷于技术分享创建公众号和博客站点对常识体系进行分享。关注公众号:青年IT男 获取最新技术文章推送!
博客地址: http://youngitman.tech
CSDN: https://blog.csdn.net/liyong1...
微信公众号:
技术交换群: