Spring Framework对单元测试的支持

本文介绍了如何在Spring框架中利用依赖注入进行单元测试,包括使用模拟对象、环境模拟、JNDI模拟以及Spring提供的各种测试支持类,如MockObjects、AopTestUtils和SpringMVCTest框架,以提高代码的可测试性和测试效率。
摘要由CSDN通过智能技术生成

https://docs.spring.io/spring-framework/reference/testing/unit.html

依赖注入应该使你的代码比传统的J2EE / Java EE开发更少依赖于容器。组成你的应用程序的POJO应该在JUnit或TestNG测试中是可测试的,对象通过使用new操作符实例化,无需Spring或任何其它容器。你可以使用模拟对象(与其它有价值的测试技术结合使用)来孤立地测试你的代码。如果你遵循Spring的架构建议,那么代码库的清晰分层和组件化将有助于更容易地进行单元测试。例如,你可以通过桩或模拟DAO或存储库接口来测试服务层对象,无需在运行单元测试时访问持久数据。

真正的单元测试通常运行非常快,因为没有运行时基础设施需要设置。将真正的单元测试作为你的开发方法论的一部分可以提升你的生产力。你可能不需要测试章节的这一部分来帮助你为基于IoC的应用程序编写有效的单元测试。然而,对于某些单元测试场景,Spring框架提供了模拟对象和测试支持类,这些都在本章中描述。

模拟对象(Mock Objects)

Spring 包含了一些专门用于模拟的包:

  • Environment
  • JNDI
  • Servlet API
  • Spring Web Reactive

Environment

org.springframework.mock.env包包含EnvironmentPropertySource抽象的模拟实现。MockEnvironmentMockPropertySource对于开发依赖于特定环境属性的代码的容器外测试非常有用。

JNDI

org.springframework.mock.jndi包包含了JNDI SPI的部分实现,你可以使用它为测试套件或独立应用程序设置一个简单的JNDI环境。例如,如果在测试代码中JDBC DataSource实例绑定到与Jakarta EE容器中相同的JNDI名称,你可以在测试场景中重用应用程序代码和配置,无需修改。

org.springframework.mock.jndi包中的模拟JNDI支持在Spring Framework 5.2中正式被弃用,推荐使用第三方的完整解决方案,如Simple-JNDI。

Servlet API

org.springframework.mock.web包包含一套全面的Servlet API模拟对象,这些对象对于测试Web上下文、控制器和过滤器非常有用。这些模拟对象主要针对与Spring的Web MVC框架一起使用,通常比动态模拟对象(如EasyMock)或其它Servlet API模拟对象(如MockObjects)更方便使用。

自Spring Framework 6.0起,org.springframework.mock.web中的模拟对象基于Servlet 6.0 API。

Spring MVC Test框架构建在模拟Servlet API对象之上,为Spring MVC提供了一个集成测试框架。

Spring Web Reactive

org.springframework.mock.http.server.reactive包包含ServerHttpRequestServerHttpResponse的模拟实现,用于WebFlux应用程序中。org.springframework.mock.web.server包包含一个依赖于这些模拟请求和响应对象的模拟ServerWebExchange

MockServerHttpRequestMockServerHttpResponse都扩展了与服务器特定实现相同的抽象基类,并与它们共享行为。例如,一旦创建,模拟请求是不可变的,但你可以使用来自ServerHttpRequestmutate()方法创建一个修改后的实例。

为了使模拟响应能够正确地执行写入操作并返回一个写入完成的处理器(即Mono<Void>),它默认采用了一个带有cache().then()的Flux,这样可以缓冲数据,使其可以在测试断言中使用。应用程序可以设置一个自定义的写入函数(例如,用于测试一个无限的数据流)。

WebTestClient构建在模拟请求和响应之上,以支持在没有HTTP服务器的情况下测试WebFlux应用程序。该客户端也可以与运行中的服务器一起用于端到端测试。

单元测试支持类

Spring 包含了一些可以帮助进行单元测试的类。它们分为两类:

  • 通用的测试实用程序(General Testing Utilities)
  • Spring MVC 测试实用程序(Spring MVC Testing Utilities)

通用的测试实用程序(General Testing Utilities)

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

AopTestUtils是一个与AOP(面向切面编程)相关的实用方法集合。你可以使用这些方法来获取隐藏在一个或多个Spring代理背后的实际目标对象的引用。例如,如果你已经使用诸如EasyMock或Mockito之类的库将一个bean配置为动态模拟,并且该模拟被包装在Spring代理中,你可能需要直接访问底层的模拟对象以配置期望并在其上执行验证。

ReflectionTestUtils是基于反射的实用方法集合。在测试场景中,当你需要改变常量的值、设置非公开字段、调用非公开的setter方法,或者在测试应用程序代码时调用非公开的配置或生命周期回调方法时,你可以使用这些方法。这些方法适用于以下用例:

  • ORM框架(如JPA和Hibernate)允许对域实体中的属性进行私有或受保护的字段访问,而不是公开的setter方法。
  • Spring对注解的支持(如@Autowired@Inject@Resource),为私有或受保护的字段、setter方法和配置方法提供了依赖注入。
  • 使用诸如@PostConstruct@PreDestroy之类的注解来为生命周期回调方法提供支持。

TestSocketUtils是一个简单实用程序,用于在本地主机上查找可用的TCP端口,以便在集成测试场景中使用。

TestSocketUtils可以用于在集成测试中启动外部服务器,该服务器将在可用的随机端口上运行。然而,这些实用工具不能保证给定端口后续的可用性,因此不可靠。建议不要使用TestSocketUtils来为服务器寻找可用的本地端口,而是依赖服务器在其选择或由操作系统分配的随机临时端口上启动的能力。要与该服务器交互,你应该查询服务器当前使用的端口。

Spring MVC 测试实用程序(Spring MVC Testing Utilities)

org.springframework.test.web包包含ModelAndViewAssert,你可以将其与JUnit、TestNG或任何其它测试框架结合使用,以进行涉及Spring MVC ModelAndView对象的单元测试。

要将Spring MVC Controller类作为POJO进行单元测试,请使用ModelAndViewAssert结合MockHttpServletRequestMockHttpSession等Spring的Servlet API模拟对象。要对你的Spring MVC和REST Controller类进行彻底的集成测试,并与你的Spring MVC WebApplicationContext配置一起使用,请改用Spring MVC Test Framework。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值