单元测试
引用文件
本文引用的文件
目录
简介
本文件面向 yudao-cloud 项目的单元测试实践,系统性介绍如何基于 JUnit 5 与 Mockito 进行高质量单元测试;详解 yudao-spring-boot-starter-test 提供的测试基类(BaseDbUnitTest、BaseRedisUnitTest、BaseDbAndRedisUnitTest、BaseMockitoUnitTest)及其适用场景;说明 H2 内存数据库与 Redis Mock 在测试中的配置与使用;并结合随机数据生成工具 Podam 的使用,给出可复用的测试编写范式与最佳实践。
项目结构
围绕单元测试的关键文件分布如下:
- 测试基类:位于 yudao-spring-boot-starter-test 模块的 ut 包中,提供不同环境的测试上下文(纯内存 DB、纯内存 Redis、DB+Redis、纯 Mockito)。
- 测试配置:位于 yudao-spring-boot-starter-test 模块的 config 包中,负责 H2 SQL 初始化与 Redis Mock 启动。
- 随机数据工具:位于 yudao-spring-boot-starter-test 模块的 util 包中,基于 Podam 生成 POJO 随机数据。
- 依赖声明:在 yudao-spring-boot-starter-test 的 pom.xml 中声明了 JUnit 5、Mockito、H2、jedis-mock、Podam 等测试依赖。
- 示例测试:各功能模块的测试类展示了如何继承测试基类、使用断言与 Mockito、以及结合随机数据与 SQL 初始化。
图表来源
- BaseDbUnitTest.java
- BaseRedisUnitTest.java
- BaseDbAndRedisUnitTest.java
- BaseMockitoUnitTest.java
- SqlInitializationTestConfiguration.java
- RedisTestConfiguration.java
- RandomUtils.java
- pom.xml(yudao-spring-boot-starter-test)
章节来源
- BaseDbUnitTest.java
- BaseRedisUnitTest.java
- BaseDbAndRedisUnitTest.java
- BaseMockitoUnitTest.java
- SqlInitializationTestConfiguration.java
- RedisTestConfiguration.java
- RandomUtils.java
- pom.xml(yudao-spring-boot-starter-test)
核心组件
- BaseDbUnitTest:提供内存 H2 数据库的完整测试上下文,适用于需要真实 SQL 执行但又无需外部数据库的场景。通过 @Sql 清理脚本确保每个测试后数据隔离。
- BaseRedisUnitTest:提供内存 Redis 的测试上下文,使用 Redisson 自动装配与内嵌 RedisMock 服务。
- BaseDbAndRedisUnitTest:同时启用内存数据库与内存 Redis,适合跨存储层的集成测试。
- BaseMockitoUnitTest:仅启用 Mockito 扩展,适合纯 Mock 的单元测试,不涉及数据库或 Redis。
- SqlInitializationTestConfiguration:替代默认懒加载下的 SQL 初始化行为,确保测试启动时正确执行 schema/data 脚本。
- RedisTestConfiguration:启动内嵌 RedisServer,支持多测试并发执行时的端口冲突规避。
- RandomUtils:基于 Podam 的随机数据工厂,提供字符串、数字、日期、枚举、集合与 POJO 的批量生成,便于构造测试数据。
章节来源
- BaseDbUnitTest.java
- BaseRedisUnitTest.java
- BaseDbAndRedisUnitTest.java
- BaseMockitoUnitTest.java
- SqlInitializationTestConfiguration.java
- RedisTestConfiguration.java
- RandomUtils.java
架构总览
下图展示了测试基类与配置之间的关系,以及依赖注入顺序与作用域:
图表来源
- BaseDbUnitTest.java
- BaseRedisUnitTest.java
- BaseDbAndRedisUnitTest.java
- SqlInitializationTestConfiguration.java
- RedisTestConfiguration.java
详细组件分析
测试基类与使用场景
- BaseDbUnitTest:适用于需要真实 SQL 执行的场景,如 Mapper/Service 层对 H2 的 CRUD 验证。通过 @Sql 在测试结束后清理数据,保证测试隔离。
- BaseRedisUnitTest:适用于缓存、分布式锁、消息队列等依赖 Redis 的逻辑,使用内嵌 RedisMock 避免外部依赖。
- BaseDbAndRedisUnitTest:适用于跨存储层的业务流程,例如先写入 DB,再更新缓存,最后校验一致性。
- BaseMockitoUnitTest:适用于纯逻辑单元测试,不访问数据库或 Redis,仅通过 Mock 验证业务分支与边界条件。
章节来源
H2 内存数据库配置与使用
- SQL 初始化:通过 SqlInitializationTestConfiguration 在测试启动阶段执行 schema/data 脚本,确保测试前后的数据库状态一致。
- 清理策略:BaseDbUnitTest 使用 @Sql 在每个测试方法结束后执行 clean.sql,避免测试间相互污染。
- MyBatis/MyBatis Plus:自动装配包含 YudaoMybatisAutoConfiguration、MybatisPlusAutoConfiguration、MybatisPlusJoinAutoConfiguration,满足复杂查询与关联查询的测试需求。
图表来源
章节来源
Redis Mock 配置与使用
- 内嵌 Redis:RedisTestConfiguration 启动 RedisServer,优先使用配置端口,若启动失败则忽略异常以兼容多容器并发场景。
- 自动装配:BaseRedisUnitTest 与 BaseDbAndRedisUnitTest 导入 YudaoRedisAutoConfiguration 与 RedissonAutoConfiguration,确保缓存客户端可用。
- 场景:适用于缓存读写、分布式锁、布隆过滤器等逻辑的单元测试。
图表来源
章节来源
Mockito 在单元测试中的应用
- 扩展启用:BaseMockitoUnitTest 通过 @ExtendWith(MockitoExtension.class) 启用 Mockito。
- 常用模式:
- @Mock:创建被测对象依赖的 Mock 实例。
- @InjectMocks:将 Mock 注入到被测对象中。
- when(...).thenReturn(...):定义桩函数返回值。
- verify(...):验证交互次数与调用参数。
- 示例参考:DataPermissionAnnotationInterceptorTest 展示了如何通过 Mockito 对 AOP 拦截器进行行为验证。
图表来源
章节来源
断言与测试方法命名规范
- 断言风格:统一使用 JUnit 5 的 Assertions API,如 assertEquals、assertTrue、assertNull 等。
- 测试方法命名:推荐使用“方法名_输入条件_期望结果”或“场景描述”的形式,便于阅读与维护。
- 示例参考:IPUtilsTest 展示了对 IP 解析结果的断言与边界值测试。
章节来源
随机数据生成工具 Podam 的使用
- RandomUtils 基于 PodamFactoryImpl,提供以下能力:
- 随机字符串、整数、日期、布尔值、短整型等基础类型。
- 针对 status/type 等字段的智能策略(如状态枚举、tinyint 范围)。
- 随机 POJO 与集合生成,并支持二次消费回调以定制字段。
- 使用建议:在测试准备阶段使用 randomPojo/randomPojoList 构造多样化测试数据,减少手写样板代码。
图表来源
章节来源