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

单元测试

依赖注入应使您的代码对容器的依赖程度低于传统 J2EE / Java EE 开发方式。构成应用程序的 POJO 对象应能在 JUnit 或 TestNG 测试中进行测试,通过使用 new 操作符实例化对象,而无需依赖 Spring 或其他容器。您可以使用 模拟对象(结合其他有价值的测试技术)来独立测试代码。若遵循 Spring 的架构建议,代码库最终形成的清晰分层和组件化将更容易进行单元测试。例如,您可以通过桩基或模拟 DAO 或存储库接口来测试服务层对象,无需在运行单元测试时访问持久化数据。spring-doc.cadn.net.cn

真正的单元测试通常运行极其迅速,因为无需启动 运行时基础设施。将真正的单元测试作为开发方法论的一部分,可以显著提升 生产效率。您可能无需借助测试章节的本部分内容,即可为基于IoC的应用程序 编写有效的单元测试。然而,对于特定的单元测试场景, Spring框架提供了本章节描述的模拟对象和测试支持类。spring-doc.cadn.net.cn

模拟对象

Spring 包含多个专门用于模拟的包:spring-doc.cadn.net.cn

环境

org.springframework.mock.env包包含了EnvironmentPropertySource抽象的模拟实现(请参阅 Bean定义配置文件PropertySource抽象)。 MockEnvironmentMockPropertySource对于开发依赖于环境特定属性的代码的容器外测试非常有用。spring-doc.cadn.net.cn

JNDI

org.springframework.mock.jndi 包包含 JNDI SPI 的部分实现,可用于为测试套件或独立应用程序搭建简单的 JNDI 环境。例如,若 JDBC DataSource 实例在测试代码中绑定的 JNDI 名称与其在 Jakarta EE 容器中的名称一致,则可在测试场景中直接复用应用程序代码及配置而无需修改。spring-doc.cadn.net.cn

自Spring Framework 5.2起,org.springframework.mock.jndi包中的模拟JNDI支持已被官方弃用,推荐使用第三方完整解决方案(如Simple-JNDI)。

Servlet API

org.springframework.mock.web 包包含一套全面的 Servlet API 模拟对象集合,这些对象对于测试 Web 上下文、控制器和过滤器非常有用。这些模拟对象专为与 Spring 的 Web MVC 框架配合使用而设计,通常比动态模拟对象(如 EasyMock)或其他 Servlet API 模拟对象(如 MockObjects)更方便使用。spring-doc.cadn.net.cn

自Spring框架6.0版本起,org.springframework.mock.web中的模拟对象已基于Servlet 6.0 API实现。

Spring MVC 测试框架基于模拟的 Servlet API 对象,为 Spring MVC 提供了一个集成测试框架。请参见 MockMvcspring-doc.cadn.net.cn

Spring Web Reactive

org.springframework.mock.http.server.reactive 包包含用于 WebFlux 应用的 ServerHttpRequestServerHttpResponse 的模拟实现。 org.springframework.mock.web.server 包包含依赖于这些模拟请求和响应对象的模拟 ServerWebExchangespring-doc.cadn.net.cn

MockServerHttpRequestMockServerHttpResponse 都从相同的抽象 基类扩展而来,就像特定于服务器的实现一样,并且与它们共享行为。例如, 模拟请求一旦创建就是不可变的,但你可以使用 ServerHttpRequest 中的 mutate() 方法 来创建一个修改后的实例。spring-doc.cadn.net.cn

为使模拟响应正确实现写入约定并返回写入完成句柄(即Mono<Void>),其默认使用Fluxcache().then()组合,该组合会缓冲数据使其可用于测试断言。 应用程序可设置自定义写入函数(例如用于测试无限流场景)。spring-doc.cadn.net.cn

WebTestClient基于模拟请求和响应构建,为测试WebFlux应用程序提供了无需HTTP服务器的支持。该客户端也可用于在运行服务器上进行端到端测试。spring-doc.cadn.net.cn

单元测试支持类

Spring 包含了许多有助于单元测试的类。它们主要分为两大类:spring-doc.cadn.net.cn

通用测试工具

org.springframework.test.util 包包含一些用于单元测试和集成测试的通用工具。spring-doc.cadn.net.cn

AopTestUtils 是AOP相关实用方法的集合。您可以使用这些方法获取隐藏在Spring代理背后的底层目标对象引用。例如,如果您通过EasyMock或Mockito等库将bean配置为动态模拟,且该模拟对象被Spring代理包装时,可能需要直接访问底层模拟对象以配置期望行为并执行验证。关于Spring核心AOP实用工具,请参阅AopUtilsAopProxyUtilsspring-doc.cadn.net.cn

ReflectionTestUtils 是一组基于反射的实用方法。您可以在测试场景中使用这些方法,例如需要更改常量的值、设置非public字段、调用非public的setter方法,或在测试应用程序代码时调用非public的配置或生命周期回调方法,适用于以下用例:spring-doc.cadn.net.cn

  • ORM框架(如JPA和Hibernate)允许在领域实体属性中使用privateprotected级字段访问,而非public级setter方法。spring-doc.cadn.net.cn

  • Spring对注解的支持(例如@Autowired@Inject@Resource), 可为privateprotected字段、setter方法和配置方法提供依赖注入。spring-doc.cadn.net.cn

  • 使用诸如 @PostConstruct@PreDestroy 之类的注解作为生命周期回调方法。spring-doc.cadn.net.cn

TestSocketUtils 是一个简单的工具,用于在 localhost 上查找可用的 TCP 端口,以便在集成测试场景中使用。spring-doc.cadn.net.cn

TestSocketUtils 可以在集成测试中使用,这些测试会在一个可用的随机端口上启动外部服务器。然而,这些工具无法保证后续某个端口的可用性,因此不可靠。与其使用 TestSocketUtils 来查找服务器的可用本地端口,建议您依赖服务器自身选择或由操作系统分配的随机临时端口的能力。要与该服务器进行交互,您应该查询服务器当前使用的端口。spring-doc.cadn.net.cn

Spring MVC测试工具

org.springframework.test.web 包包含 ModelAndViewAssert,您可将其 与 JUnit、TestNG 或其他任何测试框架结合使用,用于处理 Spring MVC ModelAndView 对象的 单元测试。spring-doc.cadn.net.cn

单元测试 Spring MVC 控制器
对Spring MVC进行单元测试Controller将类作为POJO,使用ModelAndViewAssert与……结合MockHttpServletRequest, MockHttpSession,等等由Spring提供的Servlet API模拟要对您的 Spring MVC 和 REST 进行全面的集成测试Controller类配合您的WebApplicationContext用于Spring MVC的配置,使用Spring MVC测试框架 instead.