集成测试

能够在不部署到应用程序服务器或连接到其他企业基础设施的情况下执行一些集成测试非常重要。这样做可以测试以下内容:

  • 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 TestContext 框架提供了一致的 Spring ApplicationContext 实例和 WebApplicationContext 实例加载,以及这些上下文的缓存。对加载上下文的缓存的支持很重要,因为启动时间可能会成为问题——不是因为 Spring 本身的开销,而是因为 Spring 容器实例化的对象需要时间来实例化。例如,一个包含 50 到 100 个 Hibernate 映射文件的项目可能需要 10 到 20 秒才能加载映射文件,在每个测试夹具中运行每个测试之前都会产生这种成本,会导致整体测试运行速度变慢,从而降低开发人员的生产力。

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

默认情况下,一旦加载,配置的 ApplicationContext 将被重用于每个测试。因此,设置成本仅在每个测试套件中产生一次,随后的测试执行速度要快得多。在此上下文中,“测试套件”是指在同一个 JVM 中运行的所有测试——例如,从 Ant、Maven 或 Gradle 构建中为给定项目或模块运行的所有测试。在不太可能的情况下,如果测试破坏了应用程序上下文并需要重新加载(例如,通过修改 bean 定义或应用程序对象的 state),则可以配置 TestContext 框架在执行下一个测试之前重新加载配置并重建应用程序上下文。

请参阅 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 框架 的支持类。