单元测试
相比于传统的 J2EE / Java EE 开发,依赖注入应该能让你的代码减少对容器的依赖。构成应用程序的 POJO 应该可以在 JUnit 或 TestNG 测试中进行测试,对象可以通过 new 运算符实例化,而无需 Infra 或任何其他容器。你可以使用 mock 对象(结合其他有价值的测试技术)来隔离测试你的代码。如果你遵循 Infra 的架构建议,你的代码库将具有清晰的分层和组件化结构,从而更易于进行单元测试。例如,你可以通过存根(stubbing)或模拟(mocking)DAO 或 repository 接口来测试服务层对象,而无需在运行单元测试时访问持久化数据。
真正的单元测试通常运行得非常快,因为不需要设置运行时基础设施。将真正的单元测试作为开发方法的一部分加以重视,可以提高你的生产力。你可能不需要阅读本测试章节的这一部分就能帮你编写基于 IoC 的应用程序的有效单元测试。然而,对于某些单元测试场景,TODAY Framework 提供了本章中描述的 mock 对象和测试支持类。
Mock 对象
Infra 包含许多专门用于 mocking 的包:
Environment
infra.mock.env 包包含 Environment 和 PropertySource 抽象的 mock 实现(参见 Bean 定义 Profile 和 PropertySource 抽象)。MockEnvironment 和 MockPropertySource 对于开发依赖于特定环境属性的代码的容器外测试非常有用。
JNDI
infra.mock.jndi 包包含 JNDI SPI 的部分实现,你可以使用它为测试套件或独立应用程序设置简单的 JNDI 环境。例如,如果 JDBC DataSource 实例在测试代码中绑定的 JNDI 名称与在 Jakarta EE 容器中相同,你就可以在测试场景中重用应用程序代码和配置而无需修改。
infra.mock.jndi 包中的 mock JNDI 支持自 TODAY Framework 5.2 起已正式弃用,建议使用第三方提供的完整解决方案,如 Simple-JNDI。
|
Mock API
infra.mock.web 包包含一套全面的 Servlet API mock 对象,对于测试 Web 上下文、控制器和过滤器非常有用。这些 mock 对象旨在与 Infra Web MVC 框架一起使用,并且通常比动态 mock 对象(如 EasyMock)或其他 Servlet API mock 对象(如 MockObjects)更易于使用。
Web MVC Test 框架建立在 mock Servlet API 对象之上,为 Web MVC 提供集成测试框架。参见 MockMvc。
Infra Web Reactive
infra.mock.http.server.reactive 包包含 ServerHttpRequest 和 ServerHttpResponse 的 mock 实现,用于 WebFlux 应用程序。infra.mock.web.server 包包含一个依赖于这些 mock 请求和响应对象的 mock ServerWebExchange。
MockServerHttpRequest 和 MockServerHttpResponse 与服务器特定的实现都扩展自相同的抽象基类,并与它们共享行为。例如,mock 请求一旦创建就是不可变的,但你可以使用 ServerHttpRequest 中的 mutate() 方法来创建一个修改后的实例。
为了让 mock 响应正确实现写入契约并返回写入完成句柄(即 Mono<Void>),它默认使用带有 cache().then() 的 Flux,这会缓冲数据并使其可用于测试中的断言。应用程序可以设置自定义写入函数(例如,用于测试无限流)。
WebTestClient 建立在 mock 请求和响应之上,为在没有 HTTP 服务器的情况下测试 WebFlux 应用程序提供支持。该客户端也可用于对运行中的服务器进行端到端测试。
单元测试支持类
Infra 包含许多有助于单元测试的类。它们分为两类:
通用测试工具
infra.test.util 包包含几个用于单元和集成测试的通用工具。
AopTestUtils 是一个 AOP 相关工具方法的集合。你可以使用这些方法获取隐藏在一个或多个 Infra 代理背后的底层目标对象的引用。例如,如果你使用 EasyMock 或 Mockito 等库将 bean 配置为动态 mock,并且该 mock 被包装在 Infra 代理中,你可能需要直接访问底层 mock 以对其配置期望并执行验证。有关 Infra 核心 AOP 工具,请参见 AopUtils 和 AopProxyUtils。
ReflectionTestUtils 是一个基于反射的工具方法的集合。在测试应用程序代码时,如果你需要更改常量的值、设置非 public 字段、调用非 public setter 方法,或调用非 public 配置或生命周期回调方法,可以使用这些方法。适用场景包括:
-
ORM 框架(如 JPA 和 Hibernate),它们允许对领域实体中的属性进行
private或protected字段访问,而不是publicsetter 方法。 -
Infra 对注解的支持(如
@Autowired、@Inject和@Resource),这些注解为private或protected字段、setter 方法和配置方法提供依赖注入。 -
使用
@PostConstruct和@PreDestroy等注解进行生命周期回调方法。
TestSocketUtils 是一个简单的工具,用于在 localhost 上查找可用的 TCP 端口以用于集成测试场景。
|
|
Web MVC 测试工具
infra.test.web 包包含 ModelAndViewAssert,你可以将其与 JUnit、TestNG 或任何其他测试框架结合使用,用于处理 Web MVC ModelAndView 对象的单元测试。
|
单元测试 Web MVC 控制器
要将 Web MVC Controller 类作为 POJO 进行单元测试,请使用 ModelAndViewAssert 结合来自 Infra API mocks 的 HttpMockRequestImpl、MockHttpSession 等。要结合 Web MVC 的 WebApplicationContext 配置对 Web MVC 和 REST Controller 类进行全面的集成测试,请改用 Web MVC Test Framework。
|