对于最新稳定版本,请使用 Spring Framework 7.0.6spring-doc.cadn.net.cn

集成测试

能够在无需部署到应用服务器或连接其他企业基础设施的情况下执行一些集成测试,这一点非常重要。 这样做可以让你测试诸如以下内容:spring-doc.cadn.net.cn

  • 正确配置您的 Spring IoC 容器上下文。spring-doc.cadn.net.cn

  • 使用 JDBC 或 ORM 工具进行数据访问。这可能包括 SQL 语句的正确性、Hibernate 查询、JPA 实体映射等方面。spring-doc.cadn.net.cn

Spring 框架在 spring-test 模块中为集成测试提供了一流的支持。实际 JAR 文件的名称可能包含发布版本号,也可能采用较长的 org.springframework.test 形式,具体取决于您获取该文件的来源(有关说明,请参阅依赖管理章节)。该库包含 org.springframework.test 包,其中提供了用于与 Spring 容器进行集成测试的实用类。此类测试不依赖于应用服务器或其他部署环境。这些测试的运行速度比单元测试慢,但比等效的 Selenium 测试或需要部署到应用服务器的远程测试要快得多。spring-doc.cadn.net.cn

以注解驱动的Spring TestContext 框架的形式提供了单元测试和集成测试支持。TestContext 框架与实际使用的测试框架无关,因此可以在各种环境中对测试进行增强,包括 JUnit、TestNG 等。spring-doc.cadn.net.cn

以下部分概述了 Spring 集成支持的高层目标,本章其余内容则聚焦于各个专门主题:spring-doc.cadn.net.cn

集成测试的目标

Spring 的集成测试支持具有以下主要目标:spring-doc.cadn.net.cn

接下来的几节将分别描述每个目标,并提供指向实现和配置细节的链接。spring-doc.cadn.net.cn

上下文管理与缓存

Spring TestContext 框架提供了一致的 Spring ApplicationContext 实例和 WebApplicationContext 实例加载机制,并支持对这些上下文进行缓存。支持已加载上下文的缓存非常重要,因为启动时间可能成为一个问题——这并非由于 Spring 自身的开销,而是因为由 Spring 容器实例化的对象需要一定时间来完成实例化。例如,一个包含 50 到 100 个 Hibernate 映射文件的项目可能需要 10 到 20 秒来加载这些映射文件,如果在每个测试类中运行每个测试之前都重复承担这一开销,会导致整体测试运行速度变慢,从而降低开发人员的工作效率。spring-doc.cadn.net.cn

测试类通常声明一个用于 XML 或 Groovy 配置元数据的资源位置数组(通常位于类路径中),或一个用于配置应用程序的组件类数组。这些位置或类与在生产部署中 web.xml 或其他配置文件中指定的位置或类相同或类似。spring-doc.cadn.net.cn

默认情况下,一旦加载完成,所配置的 ApplicationContext 将在每个测试中重复使用。 因此,每套测试仅需承担一次初始化开销,后续的测试执行速度会显著加快。在此上下文中,“测试套件”指的是在同一 JVM 中运行的所有测试—— 例如,针对某个项目或模块,通过 Ant、Maven 或 Gradle 构建所运行的所有测试。 在极少数情况下,如果某个测试破坏了应用上下文并需要重新加载(例如,修改了 Bean 定义或应用程序对象的状态), 可以配置 TestContext 框架,在执行下一个测试之前重新加载配置并重建应用上下文。spring-doc.cadn.net.cn

参见 上下文管理上下文缓存,了解 TestContext 框架的相关内容。spring-doc.cadn.net.cn

测试夹具的依赖注入

当 TestContext 框架加载您的应用程序上下文时,它可以(可选地)通过依赖注入来配置您的测试类实例。这提供了一种便捷的机制,利用应用程序上下文中预先配置好的 Bean 来设置测试夹具(test fixtures)。这里的一个显著优势是,您可以在各种测试场景中复用应用程序上下文(例如,用于配置 Spring 管理的对象图、事务代理、DataSource 实例等),从而避免在各个单独的测试用例中重复复杂的测试夹具设置。spring-doc.cadn.net.cn

例如,考虑这样一个场景:我们有一个类(HibernateTitleRepository),它为Title领域实体实现数据访问逻辑。我们希望编写集成测试来测试以下方面:spring-doc.cadn.net.cn

  • Spring 配置:基本上,与 HibernateTitleRepository bean 相关的所有配置是否都正确且完整?spring-doc.cadn.net.cn

  • Hibernate 映射文件配置:所有内容是否都已正确映射?是否设置了正确的懒加载(lazy-loading)配置?spring-doc.cadn.net.cn

  • HibernateTitleRepository 的逻辑:该类配置的实例是否按预期执行?spring-doc.cadn.net.cn

参见使用TestContext 框架进行测试夹具的依赖注入。spring-doc.cadn.net.cn

事务管理

在访问真实数据库的测试中,一个常见问题是它们对持久化存储状态的影响。即使使用开发数据库,状态的变更也可能影响后续的测试。此外,许多操作(例如插入或修改持久化数据)无法在事务之外执行(或验证)。spring-doc.cadn.net.cn

TestContext 框架解决了这一问题。默认情况下,该框架会为每个测试创建一个事务并在测试结束后回滚该事务。你可以编写假定事务存在的代码。如果你在测试中调用被事务代理的对象,它们将根据其配置的事务语义正确地执行。此外,如果某个测试方法在测试所管理的事务内删除了某些表中的内容,默认情况下该事务会被回滚,数据库将恢复到测试执行前的状态。事务支持是通过使用测试应用上下文中定义的 PlatformTransactionManager bean 来提供给测试的。spring-doc.cadn.net.cn

如果您希望事务提交(这种情况不常见,但在某些特定测试需要填充或修改数据库时很有用),您可以使用 @Commit 注解告知 TestContext 框架使事务提交而非回滚。spring-doc.cadn.net.cn

参见使用TestContext 框架进行事务管理。spring-doc.cadn.net.cn

用于集成测试的支持类

Spring TestContext 框架提供了多个 abstract 支持类,以简化集成测试的编写。这些基础测试类为测试框架提供了定义明确的钩子(hooks),以及便捷的实例变量和方法,使您可以访问:spring-doc.cadn.net.cn

  • ApplicationContext,用于执行显式的 bean 查找或测试整个上下文的状态。spring-doc.cadn.net.cn

  • 一个 JdbcTemplate,用于执行 SQL 语句以查询数据库。您可以在执行与数据库相关的应用程序代码之前和之后使用此类查询来确认数据库状态,并且 Spring 会确保这些查询在与应用程序代码相同的事务范围内运行。当与 ORM 工具结合使用时,请务必避免误报spring-doc.cadn.net.cn

此外,您可能希望创建自己的自定义应用程序级超类,其中包含特定于您项目的实例变量和方法。spring-doc.cadn.net.cn