|
对于最新的稳定版本,请使用 Spring Framework 7.0.6! |
单元测试
依赖注入应使您的代码对容器的依赖程度低于传统 J2EE / Java EE 开发方式。构成应用程序的 POJO 对象应能在 JUnit 或 TestNG 测试中进行测试,通过使用 new 操作符实例化对象,而无需依赖 Spring 或其他容器。您可以使用 模拟对象(结合其他有价值的测试技术)来独立测试代码。若遵循 Spring 的架构建议,代码库最终形成的清晰分层和组件化将更容易进行单元测试。例如,您可以通过桩基或模拟 DAO 或存储库接口来测试服务层对象,无需在运行单元测试时访问持久化数据。
真正的单元测试通常运行极其迅速,因为无需启动 运行时基础设施。将真正的单元测试作为开发方法论的一部分,可以显著提升 生产效率。您可能无需借助测试章节的本部分内容,即可为基于IoC的应用程序 编写有效的单元测试。然而,对于特定的单元测试场景, Spring框架提供了本章节描述的模拟对象和测试支持类。
模拟对象
Spring 包含多个专门用于模拟的包:
环境
org.springframework.mock.env包包含了Environment和PropertySource抽象的模拟实现(请参阅
Bean定义配置文件
和PropertySource抽象)。
MockEnvironment和MockPropertySource对于开发依赖于环境特定属性的代码的容器外测试非常有用。
JNDI
org.springframework.mock.jndi 包包含 JNDI SPI 的部分实现,可用于为测试套件或独立应用程序搭建简单的 JNDI 环境。例如,若 JDBC DataSource 实例在测试代码中绑定的 JNDI 名称与其在 Jakarta EE 容器中的名称一致,则可在测试场景中直接复用应用程序代码及配置而无需修改。
自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框架6.0版本起,org.springframework.mock.web中的模拟对象已基于Servlet 6.0 API实现。 |
Spring MVC 测试框架基于模拟的 Servlet API 对象,为 Spring MVC 提供了一个集成测试框架。请参见 MockMvc。
Spring Web Reactive
org.springframework.mock.http.server.reactive 包包含用于 WebFlux 应用的 ServerHttpRequest 和 ServerHttpResponse 的模拟实现。
org.springframework.mock.web.server 包包含依赖于这些模拟请求和响应对象的模拟 ServerWebExchange。
MockServerHttpRequest 和 MockServerHttpResponse 都从相同的抽象
基类扩展而来,就像特定于服务器的实现一样,并且与它们共享行为。例如,
模拟请求一旦创建就是不可变的,但你可以使用 ServerHttpRequest 中的 mutate() 方法
来创建一个修改后的实例。
为使模拟响应正确实现写入约定并返回写入完成句柄(即Mono<Void>),其默认使用Flux与cache().then()组合,该组合会缓冲数据使其可用于测试断言。
应用程序可设置自定义写入函数(例如用于测试无限流场景)。
WebTestClient基于模拟请求和响应构建,为测试WebFlux应用程序提供了无需HTTP服务器的支持。该客户端也可用于在运行服务器上进行端到端测试。
单元测试支持类
Spring 包含了许多有助于单元测试的类。它们主要分为两大类:
通用测试工具
该 org.springframework.test.util 包包含一些用于单元测试和集成测试的通用工具。
AopTestUtils 是AOP相关实用方法的集合。您可以使用这些方法获取隐藏在Spring代理背后的底层目标对象引用。例如,如果您通过EasyMock或Mockito等库将bean配置为动态模拟,且该模拟对象被Spring代理包装时,可能需要直接访问底层模拟对象以配置期望行为并执行验证。关于Spring核心AOP实用工具,请参阅AopUtils和AopProxyUtils。
ReflectionTestUtils 是一组基于反射的实用方法。您可以在测试场景中使用这些方法,例如需要更改常量的值、设置非public字段、调用非public的setter方法,或在测试应用程序代码时调用非public的配置或生命周期回调方法,适用于以下用例:
-
ORM框架(如JPA和Hibernate)允许在领域实体属性中使用
private或protected级字段访问,而非public级setter方法。 -
Spring对注解的支持(例如
@Autowired、@Inject和@Resource), 可为private或protected字段、setter方法和配置方法提供依赖注入。 -
使用诸如
@PostConstruct和@PreDestroy之类的注解作为生命周期回调方法。
TestSocketUtils 是一个简单的工具,用于在 localhost 上查找可用的 TCP 端口,以便在集成测试场景中使用。
|
|
Spring MVC测试工具
org.springframework.test.web 包包含
ModelAndViewAssert,您可将其
与 JUnit、TestNG 或其他任何测试框架结合使用,用于处理 Spring MVC ModelAndView 对象的
单元测试。
|
单元测试 Spring MVC 控制器 对Spring MVC进行单元测试Controller将类作为POJO,使用ModelAndViewAssert与……结合MockHttpServletRequest, MockHttpSession,等等由Spring提供的Servlet API模拟要对您的 Spring MVC 和 REST 进行全面的集成测试Controller类配合您的WebApplicationContext用于Spring MVC的配置,使用Spring MVC测试框架 instead.
|