Mock的概念
在软件开发中提及"mock",通常理解为模拟对象。它可以用来对系统、组件或类进行隔离。在测试过程中,我们通常关注测试对象本身的功能和行为,而对测试对象涉及的一些依赖,仅仅关注它们与测试对象之间的交互(比如是否调用、何时调用、调用的参数、调用的次数和顺序,以及返回的结果或发生的异常等),并不关注这些被依赖对象如何执行这次调用的具体细节。因此,Mock 机制就是使用 Mock 对象替代真实的依赖对象,并模拟真实场景来开展测试工作。
使用 Mock 对象完成依赖关系测试的示意图如下所示:
SpringBootTest包导入的组件
比如 JUnit、JSON Path、AssertJ、Mockito、Hamcrest 等,这里我们有必要对这些组件进行展开说明。
- JUnit:JUnit 是一款非常流行的基于 Java 语言的单元测试框架,在我们的课程中主要使用该框架作为基础的测试框架。
- JSON Path:类似于 XPath 在 XML 文档中的定位,JSON Path 表达式通常用来检索路径或设置 JSON 文件中的数据。
- AssertJ:AssertJ 是一款强大的流式断言工具,它需要遵守 3A 核心原则,即 Arrange(初始化测试对象或准备测试数据)——> Actor(调用被测方法)——>Assert(执行断言)。
- Mockito:Mockito 是 Java 世界中一款流行的 Mock 测试框架,它主要使用简洁的 API 实现模拟操作。在实施集成测试时,我们将大量使用到这个框架。
- Hamcrest:Hamcrest 提供了一套匹配器(Matcher),其中每个匹配器的设计用于执行特定的比较操作。
- JSONassert:JSONassert 是一款专门针对 JSON 提供的断言框架。
- Spring Test & Spring Boot Test:为 Spring 和 Spring Boot 框架提供的测试工具。
Spring单元测试编写
大致可以分为如下三类:
- 单元测试:一般面向方法,编写一般业务代码时,测试成本较大。涉及到的注解有
@Test
。 - 切片测试:一般面向难于测试的边界功能,介于单元测试和功能测试之间。涉及到的注解有
@RunWith
、@WebMvcTest
等。 - 功能测试:一般面向某个完整的业务功能,同时也可以使用切面测试中的mock能力,推荐使用。涉及到的注解有
@RunWith
、@SpringBootTest
等。
初始化测试环境
@SpringBootTest
@RunWith(SpringRunner.class)
复制代码
@SpringBootTest注解
默认情况下,@SpringBootTest不会启动嵌入式的服务器。您可以使用 @SpringBootTest 的 webEnvironment 属性进一步完善测试的运行方式:
- MOCK: 加载 WebApplicationContext 并提供一个 Mock 的 Servlet 环境,此时内置的 Servlet 容器并没有正式启动,可以配合
@AutoConfigureMockMvc
或@AutoConfigureWebTestClient
结合使用。
-
- 在多数场景下,一个真实的 Servlet 环境对于测试而言过于重量级,通过 MOCK 环境则可以缓解这种环境约束所带来的成本和挑战。
- RANDOM_PORT: 加载 EmbeddedWebApplicationContext 并提供一个真实的 Servlet 环境,然后使用一个随机端口启动内置容器。
- <