集成测试
能够进行一些集成测试而无需部署到应用程序服务器或连接到其他企业基础设施非常重要。这样做可以测试以下内容:
-
Spring IoC 容器上下文的正确连接。
-
使用 JDBC 或 ORM 工具进行数据访问。这可能包括 SQL 语句、Hibernate 查询、JPA 实体映射等的正确性。
Spring 框架在spring-test
模块中为集成测试提供了第一类支持。实际 JAR 文件的名称可能包含发行版本,也可能采用长org.springframework.test
形式,具体取决于您从哪里获取它(有关说明,请参阅依赖管理部分)。此库包含org.springframework.test
包,其中包含用于与 Spring 容器进行集成测试的宝贵类。此测试不依赖于应用程序服务器或其他部署环境。此类测试的运行速度比单元测试慢,但比依赖于部署到应用程序服务器的等效 Selenium 测试或远程测试快得多。
单元和集成测试支持以基于注解的Spring TestContext 框架的形式提供。TestContext 框架与实际使用的测试框架无关,允许在各种环境中检测测试,包括 JUnit、TestNG 等。
下一节概述了 Spring 集成支持的高级目标,本章的其余部分将重点介绍专用主题。
集成测试的目标
Spring 的集成测试支持的主要目标如下:
-
提供测试装置实例的依赖注入。
-
提供适合集成测试的事务管理。
-
提供Spring 特定的基类,以帮助开发人员编写集成测试。
接下来的几节将描述每个目标,并提供实现和配置详细信息的链接。
上下文管理和缓存
Spring TestContext 框架提供 Spring ApplicationContext
实例和WebApplicationContext
实例的一致加载以及这些上下文的缓存。对加载上下文的缓存的支持非常重要,因为启动时间可能会成为问题——不是因为 Spring 本身的开销,而是因为 Spring 容器实例化的对象需要时间来实例化。例如,具有 50 到 100 个 Hibernate 映射文件的项目可能需要 10 到 20 秒才能加载映射文件,并且在运行每个测试装置中的每个测试之前都要承担此成本,会导致整体测试运行速度变慢,从而降低开发人员的生产力。
测试类通常声明 XML 或 Groovy 配置元数据的资源位置数组(通常在类路径中),或者声明用于配置应用程序的组件类数组。这些位置或类与生产部署中在web.xml
或其他配置文件中指定的那些位置或类相同或相似。
默认情况下,加载后,配置的ApplicationContext
将被重用于每个测试。因此,设置成本每个测试套件只产生一次,随后的测试执行速度要快得多。“测试套件”是指在同一 JVM 中运行的所有测试——例如,针对给定项目或模块运行的 Ant、Maven 或 Gradle 构建运行的所有测试。在不太可能的情况下,测试会损坏应用程序上下文并需要重新加载(例如,通过修改 Bean 定义或应用程序对象的状态),可以配置 TestContext 框架在执行下一个测试之前重新加载配置并重建应用程序上下文。
测试装置的依赖注入
当 TestContext 框架加载应用程序上下文时,它可以选择使用依赖注入来配置测试类的实例。这提供了一种方便的机制,可以使用应用程序上下文中的预配置 Bean 来设置测试装置。这里的一个显著优势是,您可以跨各种测试场景重用应用程序上下文(例如,用于配置 Spring 托管的对象图、事务代理、DataSource
实例等),从而避免需要为各个测试用例重复复杂的测试装置设置。
例如,考虑一个场景,我们有一个类(HibernateTitleRepository
)实现Title
域实体的数据访问逻辑。我们希望编写集成测试来测试以下方面:
-
Spring 配置:基本上,
HibernateTitleRepository
Bean 的所有相关配置是否正确且存在? -
Hibernate 映射文件配置:所有内容是否正确映射,并且是否启用了正确的延迟加载设置?
-
HibernateTitleRepository
的逻辑:此类的配置实例是否按预期执行?
请参阅使用TestContext 框架进行测试装置的依赖注入。
事务管理
访问真实数据库的测试中一个常见问题是它们对持久化存储状态的影响。即使使用开发数据库,状态的更改也可能会影响未来的测试。此外,许多操作(例如插入或修改持久性数据)无法在事务之外执行(或验证)。
TestContext 框架解决了这个问题。默认情况下,该框架为每个测试创建并回滚一个事务。您可以编写假设事务存在的代码。如果您在测试中调用事务代理对象,它们会根据其配置的事务语义正确运行。此外,如果测试方法在为测试管理的事务中运行时删除了所选表的內容,则事务默认情况下会回滚,并且数据库会恢复到测试执行之前的状态。事务支持是通过使用在测试的应用程序上下文中定义的PlatformTransactionManager
bean 来提供给测试的。
如果您希望事务提交(不常见,但在您希望特定测试填充或修改数据库时偶尔有用),您可以使用@Commit
注解告诉 TestContext 框架使事务提交而不是回滚。
请参阅使用TestContext 框架进行事务管理。
集成测试的支持类
Spring TestContext 框架提供了一些abstract
支持类,简化了集成测试的编写。这些基测试类为测试框架提供了明确定义的挂钩,以及方便的实例变量和方法,允许您访问
-
ApplicationContext
,用于执行显式 bean 查找或测试上下文的整体状态。 -
JdbcTemplate
,用于执行 SQL 语句来查询数据库。您可以使用此类查询来确认数据库状态在执行与数据库相关的应用程序代码之前和之后的状态,Spring 确保此类查询在与应用程序代码相同的范围内运行。当与 ORM 工具结合使用时,请务必避免误报。
此外,您可能希望创建自己的自定义应用程序范围的超类,其中包含特定于您项目的实例变量和方法。
请参阅TestContext 框架的支持类。