Unit Testing
依赖注入使代码更独立于容器,揭示 POJO 的可测试性。通过模拟对象、专门的测试支持类和 Spring 的体系结构建议,单元测试可以轻松进行,隔离代码并提高效率。模拟对象和测试支持类允许在不涉及运行时基础架构的情况下测试代码,从而提高开发效率。
依赖注入应该可以让你的代码比使用传统的 J2EE/Java EE 开发更不依赖于容器。构成你的应用程序的 POJO 应该可以在 JUnit 或 TestNG 测试中进行测试,其中对象是使用 new
运算符实例化的,而无需 Spring 或任何其他容器。你可以使用 mock objects (结合其他有价值的测试技术)来孤立地测试你的代码。如果你遵循 Spring 的架构建议,生成的干净分层和你的代码库的组件化将有助于更轻松地进行单元测试。例如,你可以通过存根或模拟 DAO 或存储库接口来测试服务层对象,而无需在运行单元测试时访问持久性数据。
真正的单元测试通常运行得非常快,因为没有运行时基础架构要设置。强调作为开发方法的一部分而进行的真正的单元测试可以提高你的工作效率。你可能不需要此测试章节部分来帮助你为基于 IoC 的应用程序编写有效的单元测试。然而,对于某些单元测试场景,Spring 框架提供了模拟对象和测试支持类,其中介绍的内容见本章节。
Mock Objects
Spring 包含许多专用于模拟的包:
Environment
org.springframework.mock.env
包含`Environment` 和 PropertySource
抽象的模拟实现(见Bean Definition Profiles和PropertySource
Abstraction)。MockEnvironment
和 MockPropertySource
对于开发对环境特定属性有依赖关系的代码的容器外测试非常有用。
JNDI
org.springframework.mock.jndi
包包含 JNDI SPI 的部分实现,你可以使用该部分实现为测试套件或独立应用程序设置一个简单的 JNDI 环境。例如,如果 JDBC DataSource
实例在测试代码中与它们在 Jakarta EE 容器中的相同 JNDI 名称绑定,你就可以在测试场景中重用应用程序代码和配置,而无需进行修改。
包中的模拟 JNDI 支持 org.springframework.mock.jndi
在 Spring Framework 5.2 中正式弃用,取而代之的是来自第三方(如 Simple-JNDI)的完整解决方案。
Servlet API
org.springframework.mock.web
包含一组全面的 Servlet API 模拟对象,这些对象对于测试 Web 上下文、控制器和过滤器很有用。这些模拟对象的目标是与 Spring 的 Web MVC 框架一起使用,并且通常比动态模拟对象(如 EasyMock )或备用的 Servlet API 模拟对象(如 MockObjects )更方便使用。
自 Spring 框架 6.0 起, |
MockMvc 基于 servlet API 模拟对象构建,为 Spring MVC 提供了集成测试框架。请参见 MockMvc 。
Spring Web Reactive
org.springframework.mock.http.server.reactive
包包含 ServerHttpRequest
和 ServerHttpResponse
的模拟实现,用于在 WebFlux 应用程序中使用。org.springframework.mock.web.server
包包含一个模拟的 ServerWebExchange
,它依赖于那些模拟请求和响应对象。
MockServerHttpRequest
和 MockServerHttpResponse
都从与特定于服务器的实现相同的抽象基类扩展,并与它们共享行为。例如,模拟请求在创建后是不可变的,但你可以使用 ServerHttpRequest
中的 mutate()
方法创建一个已修改的实例。
为了让模拟响应正确实现写契约并返回写完成处理程序(即 Mono<Void>
),它默认使用带有 cache().then()
的 Flux
,它会缓冲数据并使其在测试中可用于断言。应用程序可以设置自定义写函数(例如,测试一个无限流)。
WebTestClient 基于模拟请求和响应构建,以提供在没有 HTTP 服务器的情况下测试 WebFlux 应用程序的支持。客户端还可以用于对正在运行的服务器进行端到端测试。
Unit Testing Support Classes
Spring 包含许多可以帮助进行单元测试的类。它们分为两类:
General Testing Utilities
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
设置器方法。 -
Spring 对注释的支持(如
@Autowired
、@Inject
和@Resource
),这些注释为private
或protected
字段、设置器方法和配置方法提供依赖项注入。 -
使用诸如
@PostConstruct
和@PreDestroy
的注释用于生命周期回调方法。
TestSocketUtils
是一个简单的实用程序,用于发现 localhost
上可用的 TCP 端口,以便在集成测试场景中使用。
|
Spring MVC Testing Utilities
org.springframework.test.web
包含 ModelAndViewAssert
,您可以将其与 JUnit、TestNG 或任何其他测试框架结合使用,以对处理 Spring MVC ModelAndView
对象的单元测试。
Unit testing Spring MVC Controllers
要将你的 Spring MVC |