依赖注入应该使代码对容器的依赖性降低 使用传统的 J2EE / Java EE 开发。构成应用程序的 POJO 应该在 JUnit 或 TestNG 测试中可测试,使用运算符实例化对象,无需 Spring 或任何其他容器。您可以使用模拟对象(结合使用其他有价值的测试技术)来单独测试代码。 如果遵循 Spring 的架构建议,则生成的干净分层 和代码库的组件化有助于更轻松的单元测试。例如 您可以通过存根或模拟 DAO 或存储库接口来测试服务层对象, 无需在运行单元测试时访问持久性数据。new

真正的单元测试通常运行得非常快,因为没有运行时基础结构来 建立。强调真正的单元测试作为开发方法的一部分可以提高 您的生产力。您可能不需要测试章节的这一部分来帮助您编写 对基于 IoC 的应用程序进行有效的单元测试。对于某些单元测试方案, 但是,Spring Framework 提供了模拟对象和测试支持类,它们 在本章中进行了描述。

模拟对象

Spring 包含许多专门用于模拟的软件包:

环境

该包包含 and 抽象的模拟实现(请参见 Bean 定义配置文件PropertySource 抽象)。 并且对开发很有用 对依赖于特定于环境的属性的代码进行容器外测试。org.springframework.mock.envEnvironmentPropertySourceMockEnvironmentMockPropertySource

JNDI公司

该软件包包含 JNDI 的部分实现 SPI,可用于为测试套件或独立测试套件设置简单的 JNDI 环境 应用。例如,如果 JDBC 实例绑定到同一个 JNDI 与在 Jakarta EE 容器中一样,您可以重用这两个应用程序代码 和测试场景中的配置,无需修改。org.springframework.mock.jndiDataSource

软件包中的模拟 JNDI 支持是 从 Spring Framework 5.2 开始正式弃用,取而代之的是来自第三方的完整解决方案 Simple-JNDI等政党。org.springframework.mock.jndi

Servlet API

该软件包包含一整套 Servlet API 模拟对象,这些对象可用于测试 Web 上下文、控制器和筛选器。这些 mock 对象针对 Spring 的 Web MVC 框架使用,通常更多 比动态模拟对象(如 EasyMock)更方便使用 或替代 Servlet API 模拟对象(例如 MockObjects)。org.springframework.mock.web

从 Spring Framework 6.0 开始,中的模拟对象是 基于 Servlet 6.0 API。org.springframework.mock.web

Spring MVC 测试框架基于模拟 Servlet API 对象构建,以提供 Spring MVC 的集成测试框架。请参阅 MockMvc

Spring Web 反应式

该包包含模拟实现 用于 WebFlux 应用程序。该包包含一个模拟 取决于这些模拟请求和响应对象。org.springframework.mock.http.server.reactiveServerHttpRequestServerHttpResponseorg.springframework.mock.web.serverServerWebExchange

两者都是从同一个抽象扩展而来的 基类作为特定于服务器的实现,并与它们共享行为。为 例如,模拟请求在创建后是不可变的,但您可以使用该方法 from 创建修改后的实例。MockServerHttpRequestMockServerHttpResponsemutate()ServerHttpRequest

为了让模拟响应正确实现写入合约并返回一个 写完成句柄(即 ),默认情况下,它使用 with ,它缓冲数据并使其可用于测试中的断言。 应用程序可以设置自定义写入函数(例如,测试无限流)。Mono<Void>Fluxcache().then()

WebTestClient 基于模拟请求和响应构建,以支持 在没有 HTTP 服务器的情况下测试 WebFlux 应用程序。该客户端还可用于 使用正在运行的服务器进行端到端测试。

单元测试支持类

Spring 包含许多可以帮助进行单元测试的类。它们分为两部分 类别:

常规测试实用程序

该软件包包含多个通用实用程序 用于单元和集成测试。org.springframework.test.util

AopTestUtils 是 与 AOP 相关的实用程序方法。您可以使用这些方法获取对 隐藏在一个或多个 Spring 代理后面的基础目标对象。例如,如果您 使用 EasyMock 或 Mockito 等库将 Bean 配置为动态模拟, 并且模拟被包装在 Spring 代理中,您可能需要直接访问底层 mock 配置对它的期望并执行验证。对于 Spring 的核心 AOP 实用程序,请参阅 AopUtilsAopProxyUtils

ReflectionTestUtils 是一个 基于反射的实用方法的集合。您可以在测试中使用这些方法 需要更改常量值、设置非字段、 调用非 setter 方法,或调用非配置或生命周期 测试应用程序代码时的回调方法,例如:publicpublicpublic

  • ORM 框架(如 JPA 和 Hibernate)纵容或字段 访问,而不是域实体中属性的 setter 方法。privateprotectedpublic

  • Spring 对注解(如 、 、 和 )、 的支持 为 OR 字段、setter 方法提供依赖注入、 和配置方法。@Autowired@Inject@Resourceprivateprotected

  • 使用 和 等注释进行生命周期回调 方法。@PostConstruct@PreDestroy

TestSocketUtils 是一个简单的 用于查找可用于集成测试的可用 TCP 端口的实用程序 场景。localhost

TestSocketUtils可用于在 可用的随机端口。但是,这些实用程序不保证后续 给定端口的可用性,因此不可靠。建议不要使用查找服务器的可用本地端口,而是 您依赖于服务器在它选择或正在选择的随机临时端口上启动的能力 由操作系统分配。要与该服务器交互,您应该查询 服务器,用于当前使用的端口。TestSocketUtils

Spring MVC 测试实用程序

该包包含 ModelAndViewAssert,其中 可以与 JUnit、TestNG 或任何其他测试框架结合使用进行单元测试 处理 Spring MVC 对象。org.springframework.test.webModelAndView

单元测试 Spring MVC 控制器
要将 Spring MVC 类作为 POJO 进行单元测试,请结合使用 Spring 的 Servlet API 模拟中的 、 等。为了对您的 Spring MVC 和 REST 类与 Spring MVC 的配置结合使用,请改用 Spring MVC 测试框架ControllerModelAndViewAssertMockHttpServletRequestMockHttpSessionControllerWebApplicationContext