# 3.2集成测试的目的

Spring的集成测试支持有以下主要目标：

* 在测试之间管理Spring IoC容器缓存。
* 提供测试装置实例的依赖注入。
* 提供适合集成测试的事务管理。
* 提供特定于Spring的基类，帮助开发人员编写集成测试。

接下来的几节将介绍每个目标，并提供实现和配置详细信息的链接。

## 3.2.1 上下文管理和缓存

Spring TestContext Framework提供Spring ApplicationContext实例和WebApplicationContext实例的一致加载以及这些上下文的缓存。支持缓存加载的上下文非常重要，因为启动时间可能会成为一个问题 - 不是因为Spring本身的开销，而是因为Spring容器实例化的对象需要时间来实例化。例如，具有50到100个Hibernate映射文件的项目可能需要10到20秒来加载映射文件，并且在每个测试装置中运行每个测试之前产生该成本会导致整体测试运行速度变慢，从而降低开发人员的工作效率。

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

默认情况下，一旦加载，配置的ApplicationContext将重复用于每个测试。因此，每个测试套件仅产生一次设置成本，并且后续测试执行要快得多。在此上下文中，术语“测试套件”表示所有测试都在同一JVM中运行 - 例如，所有测试都是针对给定项目或模块从Ant，Maven或Gradle构建的。在不太可能的情况下，测试会破坏应用程序上下文并需要重新加载（例如，通过修改bean定义或应用程序对象的状态），可以将TestContext框架配置为在执行下一个之前重新加载配置并重建应用程序上下文测试。

请参阅使用TestContext框架的上下文管理和上下文缓存。

## 3.2.2 测试装置的依赖注入

当TestContext框架加载应用程序上下文时，它可以选择使用依赖注入来配置测试类的实例。这提供了一种方便的机制，可以通过使用应用程序上下文中的预配置bean来设置测试装置。这里的一个重要好处是你可以在各种测试场景中重用应用程序上下文（例如，用于配置Spring管理的对象图，事务代理，DataSource实例等），从而避免复制单个测试的复杂测试装置设置的需要案例。

作为示例，考虑我们有一个类（HibernateTitleRepository）实现Title域实体的数据访问逻辑的场景。我们想编写测试以下方面的集成测试：

* Spring配置：基本上，与HibernateTitleRepository bean的配置相关的所有内容是否正确和存在？
* Hibernate映射文件配置：是否所有映射都正确并且是否正确的延迟加载设置？
* HibernateTitleRepository的逻辑：此类的已配置实例是否按预期执行？

请参阅使用TestContext框架对测试装置进行依赖注入。

## 3.2.3 事务管理

访问真实数据库的测试中的一个常见问题是它们对持久性存储的状态的影响。即使你使用开发数据库，​​对状态的更改也可能会影响将来的测试。此外，许多操作（例如插入或修改持久数据）无法在事务之外执行（或验证）。

TestContext框架解决了这个问题。默认情况下，框架为每个测试创建并回滚事务。你可以编写可以假定存在事务的代码。如果在测试中调用事务代理对象，则根据其配置的事务语义，它们的行为正确。此外，如果测试方法在为测试管理的事务中运行时删除所选表的内容，则事务默认回滚，并且数据库返回到执行测试之前的状态。通过使用在测试的应用程序上下文中定义的PlatformTransactionManager bean，为测试提供事务支持。

如果你希望事务提交（异常，但在你希望特定测试填充或修改数据库时偶尔有用），你可以通过使用@Commit注解告诉TestContext框架使事务提交而不是回滚。

使用TestContext框架查看事务管理。

## 3.2.4 集成测试的支持类

Spring TestContext Framework提供了几个抽象支持类，可以简化集成测试的编写。 这些基本测试类提供了定义良好的钩子到测试框架中，以及方便的实例变量和方法，使你可以访问：

* ApplicationContext，用于执行显式bean查找或测试整个上下文的状态。
* JdbcTemplate，用于执行SQL语句以查询数据库。 你可以在执行与数据库相关的应用程序代码之前和之后使用此类查询来确认数据库状态，Spring确保此类查询在与应用程序代码相同的事务范围内运行。 与ORM工具结合使用时，请务必避免误报。

此外，你可能希望使用特定于项目的实例变量和方法创建自己的自定义应用程序范围的超类。

请参阅TestContext框架的支持类。
