2.1 Mockito核心API详解
Mockito核心API详解
1. 创建Mock对象
Mockito提供两种方式创建模拟对象:
1.1 手动创建(传统方式)
// 创建接口/类的Mock对象
UserDao userDao = Mockito.mock(UserDao.class);
1.2 注解驱动(推荐方式)
结合JUnit 5的扩展机制,自动管理Mock生命周期:
@ExtendWith(MockitoExtension.class) // 启用Mockito支持
class UserServiceTest {@Mock // 自动创建Mock对象private UserDao mockUserDao;@InjectMocks // 自动注入@Mock对象到被测类private UserService userService;
}
选择策略:
- 简单测试 → 手动创建
- 多依赖测试 → 注解驱动(避免重复代码)
2. 方法桩(Stubbing)
控制Mock对象方法的返回值或异常抛出。
2.1 基础配置
// 返回固定值
when(mockUserDao.findById(1)).thenReturn(new User("Alice"));// 抛出异常
when(mockUserDao.save(any())).thenThrow(new DatabaseException());// 连续配置(依次返回)
when(mockList.get(0)).thenReturn("A", "B", "C"); // 第一次"A",第二次"B"...
2.2 动态响应
// 根据输入参数动态计算返回值
when(mockCalculator.add(anyInt(), anyInt())).thenAnswer(invocation -> {int a = invocation.getArgument(0);int b = invocation.getArgument(1);return a + b;
});// 调用真实方法(部分保留逻辑)
when(mockUserDao.findById(1)).thenCallRealMethod();
2.3 Void方法处理
// 默认不做任何事情
doNothing().when(mockLogger).writeLog(anyString());// 抛出异常
doThrow(new IOException()).when(mockFileService).deleteFile(any());
3. 验证交互行为
验证Mock对象的方法是否按预期被调用。
3.1 基础验证
verify(mockUserDao).findById(1); // 验证方法被调用一次
3.2 调用次数验证
verify(mockUserDao, times(2)).update(any()); // 精确次数
verify(mockUserDao, atLeastOnce()).delete(5); // 至少一次
verify(mockUserDao, never()).findAll(); // 从未调用
3.3 顺序验证
InOrder inOrder = inOrder(mockA, mockB);
inOrder.verify(mockA).prepare();
inOrder.verify(mockB).execute();
3.4 超时验证(异步场景)
// 200ms内至少调用一次
verify(mockAsyncService, timeout(200)).callback();
4. 参数匹配器(Argument Matchers)
灵活匹配方法参数,增强测试的适应性和可读性。
4.1 内置匹配器
// 任意字符串参数
when(mockUserDao.findByUsername(anyString())).thenReturn(...);// 混合精确与模糊匹配
when(service.process(eq("order"), anyInt())).thenReturn(true);
4.2 自定义匹配器
// 定义复杂参数条件
verify(mockValidator).validate(argThat(user -> user.getAge() > 18 && user.isVerified()
));
注意事项:
- 若方法中多个参数使用匹配器,所有参数必须都用匹配器
- 避免过度使用
any()→ 可能导致测试条件过于宽松
5. 高级功能API
5.1 Spy对象(部分真实对象)
List<String> realList = new ArrayList<>();
List<String> spyList = spy(realList); // 保留真实方法// 覆盖特定方法行为
doReturn(false).when(spyList).isEmpty();
5.2 参数捕获(ArgumentCaptor)
@Captor // 自动初始化
private ArgumentCaptor<User> userCaptor;@Test
void testSaveUser() {userService.register("Bob");verify(mockUserDao).save(userCaptor.capture());User capturedUser = userCaptor.getValue();assertEquals("Bob", capturedUser.getName());
}
5.3 重置Mock状态
reset(mockUserDao); // 慎用!通常表示测试设计有问题
核心API对照表
| API | 典型应用场景 |
|---|---|
mock() / @Mock | 创建完全模拟的假对象 |
when().thenReturn() | 配置方法返回固定值 |
verify() | 验证方法调用情况 |
any() / eq() | 参数灵活匹配 |
@Spy | 需要保留部分真实逻辑的对象 |
ArgumentCaptor | 深入分析传入方法的参数内容 |
最佳实践建议
- 优先使用注解驱动:
@Mock+@InjectMocks提升代码可读性和维护性。 - 精确验证参数:
避免过度使用any(),尽可能用eq()或具体值匹配关键参数。 - 及时清理过时桩:
使用Mockito.clearInvocations(mock)而非reset()。 - 保持测试原子性:
每个测试方法只验证一个明确的业务场景。
通过掌握这些核心API,开发者可以高效构建可靠、易维护的单元测试体系。接下来可进入参数匹配器实战学习更精细的控制技巧。
相关文章:
2.1 Mockito核心API详解
Mockito核心API详解 1. 创建Mock对象 Mockito提供两种方式创建模拟对象: 1.1 手动创建(传统方式) // 创建接口/类的Mock对象 UserDao userDao Mockito.mock(UserDao.class);1.2 注解驱动(推荐方式) 结合JUnit 5的…...
傅里叶单像素成像技术研究进展
摘要:计算光学成像,通过光学系统和信号处理的有机结合与联合优化实现特定成像特性的成像系统,摆脱了传统成像系统的限制,为光学成像技术添加了浓墨重彩的一笔,并逐步向简单化与智能化的方向发展。单像素成像(Single-Pi…...
可视化工作流编排参数配置完整方案设计文档
一、背景及需求分析 1. 背景 在复杂的工作流程中,后续程序需要动态构造输入参数,这些参数源自多个前序程序的 JSON 数据输出。为了增强系统的灵活性和可扩展性,配置文件需要支持以下功能: 灵活映射前序程序的 JSON 数据。…...
镜头放大倍率和像素之间的关系
相互独立的特性 镜头放大倍率:主要取决于镜头的光学设计和结构,决定了镜头对物体成像时的缩放程度,与镜头的焦距等因素密切相关。比如,微距镜头具有较高的放大倍率,能将微小物体如昆虫、花朵细节等放大成像࿰…...
MariaDB *MaxScale*实现mysql8读写分离
1.MaxScale 是干什么的? MaxScale是maridb开发的一个mysql数据中间件,其配置简单,能够实现读写分离,并且可以根据主从状态实现写库的自动切换,对多个从服务器能实现负载均衡。 2.MaxScale 实验环境 中间件192.168.12…...
计算机毕业设计Spark+大模型知网文献论文推荐系统 知识图谱 知网爬虫 知网数据分析 知网大数据 知网可视化 预测系统 大数据毕业设计 机器学习
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
MySQL的事务实现原理和隔离级别?
目录 MySQL 事务实现原理 1. 事务的基本概念 2. 实现原理 日志系统 锁机制 MySQL 隔离级别 1. 隔离级别概述 2. 各隔离级别详解 读未提交(Read Uncommitted) 读已提交(Read Committed) 可重复读(Repeatable Read) 串行化(Serializable) 3. 设置隔离级别 My…...
JVM做GC垃圾回收时需要多久,都由哪些因素决定的
JVM进行垃圾回收(GC)的时间长短受多种因素影响,主要包括以下几个方面: 1. 堆内存大小 堆内存越大,GC需要扫描和回收的对象越多,耗时越长。堆内存较小时,GC频率增加,但每次回收的时…...
padding: 20rpx 0rpx 20rpx 20rpx(上、右、下、左的填充(顺时针方向))
CSS样式 padding: 20rpx 0rpx 20rpx 20rpx; 用于设置元素的填充区域。以下是对每个值的详细解释: 20rpx(上边距):设置元素顶部的填充为20rpx。0rpx(右边距):设置元素右侧的填充为0rpx。20rpx&a…...
2025-2-10-4.4 双指针(基础题1)
文章目录 4.4 双指针(基础题)**344. 反转字符串****125. 验证回文串****1750. 删除字符串两端相同字符后的最短长度****167.两数之和 II - 输入有序数组****2105. 给植物浇水 II****977. 有序数组的平方****658. 找到K个最接近的元素****1471. 数组中的k…...
Qt - 地图相关 —— 2、Qt调用百度在线地图功能示例全集,包含线路规划、地铁线路查询等(附源码)
效果:由于录制软件导致exe显示不正常,实际运行没有任何问题。 说明:exe试用下载(提取码: 4d8y )...
微信小程序如何使用decimal计算金额
第三方库地址:GitHub - MikeMcl/decimal.js: An arbitrary-precision Decimal type for JavaScript 之前都是api接口走后端计算,偶尔发现这个库也不错,计算简单,目前发现比较准确 上代码 导入js import Decimal from ../../uti…...
【AI学习】关于 DeepSeek-R1的几个流程图
遇见关于DeepSeek-R1的几个流程图,清晰易懂形象直观,记录于此。 流程图一 来自文章《Understanding Reasoning LLMs》, 文章链接:https://magazine.sebastianraschka.com/p/understanding-reasoning-llms?continueFlagaf07b1a0…...
C++模板编程——typelist的实现
文章最后给出了汇总的代码,可直接运行 1. typelist是什么 typelist是一种用来操作类型的容器。和我们所熟知的vector、list、deque类似,只不过typelist存储的不是变量,而是类型。 typelist简单来说就是一个类型容器,能够提供一…...
Python3 ImportError: cannot import name ‘XXX‘ from ‘XXX‘
个人博客地址:Python3 ImportError: cannot import name XXX from XXX | 一张假钞的真实世界 例如如下错误: $ python3 git.py Traceback (most recent call last):File "git.py", line 1, in <module>from git import RepoFile &quo…...
数据可视化与交互融合:APP 界面设计的新维度
在数字化浪潮汹涌的当下,APP 已成为人们生活和工作中不可或缺的工具。如何在众多 APP 中脱颖而出,界面设计至关重要。而数据可视化与交互的融合,正为 APP 界面设计开辟了全新的维度。 数据可视化,简单来说,就是将复杂…...
502 Bad Gateway 错误详解:从表现推测原因,逐步排查直至解决
502 Bad Gateway 错误通常意味着服务器之间的通信失败,但导致的具体原因往往因场景而异。 场景一:高峰期频繁出现 502 错误 1.1 现象 在流量高峰期间(如促销活动、直播发布等),页面访问变慢甚至出现 502 错误&#…...
控制论与信息论:维纳和香农的核心分歧在于对「信息本质」的理解
控制论与信息论:维纳和香农的核心分歧在于对「信息本质」的理解 核心结论 控制论是「系统的方向盘」,通过反馈调节实现目标信息论是「信息的尺子」,量化信息传输的精度与效率根本分歧:维纳认为信息是「系统维持秩序的工具」&…...
Baklib优化数字化内容管理用科技提升商业效率与增值潜力
内容概要 在当今数字化迅速发展的时代,数字化内容管理已成为企业提升竞争力的重要手段。Baklib作为一款强大的智能优化内容管理系统,通过先进的科技手段,帮助企业在内容管理和数据整合方面实现高效运作。Baklib 是什么类型的工具,…...
一个基于ESP32S3和INMP441麦克风实现音频强度控制RGB灯带律动的代码及效果展示
一个基于ESP32S3和INMP441麦克风实现音频强度控制RGB灯带律动的代码示例,使用Arduino语言: 硬件连接 INMP441 VCC → ESP32的3.3VINMP441 GND → ESP32的GNDINMP441 SCK → ESP32的GPIO 17INMP441 WS → ESP32的GPIO 18INMP441 SD → ESP32的GPIO 16RG…...
利用二分法进行 SQL 时间盲注
什么是时间盲注? SQL 盲注(Blind SQL Injection)是一种常见的 Web 安全漏洞,其中时间盲注是基于查询延迟的 SQL 注入方式。当服务器不返回可见的错误信息时,我们可以利用 SLEEP() 函数来判断查询结果是否符合预期。 …...
Linux运维——用户管理
Linux用户管理 一、Linux用户管理要点二、常用命令2.1、groupadd2.2、groupdel2.3、groupmod2.4、groups2.5、useradd2.6、userdel2.7、passwd2.9、su2.10、sudo2.10.1、给普通用户授权 sudo2.10.2、 免密码授权 sudo 一、Linux用户管理要点 创建用户组 - 使用 groupadd删除用…...
基于STM32的声纹识别智能门锁
一、项目背景与意义 行业痛点:传统指纹锁存在表皮磨损识别失败风险,声纹具备活体检测特性 技术优势: - 采用MFCC(梅尔频率倒谱系数)替代传统FFT,提升说话人特征区分度 - 动态时间规整(DTW)算法解决语…...
【密评】 | 商用密码应用安全性评估从业人员考核题库(19)
在SM9数字签名的生成和验证过程之前,杂凑函数( )。 A.仅对待签名消息进行压缩 B.仅对待验证消息进行压缩 C.对待签名消息和待验证消息都要压缩 D.不起任何作用 SM9密钥封装机制封装的秘密密钥是( )生成的。 A.根据主公钥 B.根据接受者的用户标识 C.由随机数发生器 D.以上都…...
redis底层数据结构——链表
文章目录 定义内部实现总结 定义 链表提供了高效的节点重排能力,以及顺序性的节点访间方式,并且可以通过增删节点来灵活地调整链表的长度。 作为一种常用数据结构,链表内置在很多高级的编程语言里面,因为Redis使用的C语言并没有…...
在CT107D单片机综合训练平台上实现外部中断控制LED闪烁
引言 在单片机开发中,外部中断是一个非常重要的功能,它可以让单片机在检测到外部信号变化时立即做出响应。本文将详细介绍如何在CT107D单片机综合训练平台上使用外部中断来控制LED灯的闪烁。我们将使用两种不同的方式来实现这一功能:一种是在…...
C++ Primer 类型转换
欢迎阅读我的 【CPrimer】专栏 专栏简介:本专栏主要面向C初学者,解释C的一些基本概念和基础语言特性,涉及C标准库的用法,面向对象特性,泛型特性高级用法。通过使用标准库中定义的抽象设施,使你更加适应高级…...
芋道源码(无遮羞布版)Spring Boot 全景指南
芋道源码(无遮羞布版)Spring Boot 全景指南 项目地址:https://gitcode.com/gh_mirrors/ru/ruoyi-spring-boot-all 一、项目目录结构及介绍 芋道源码(ruoyi-spring-boot-all)项目基于Spring Boot构建,旨在提供一个全…...
Visual Studio Code中文出现黄色框子的解决办法
Visual Studio Code中文出现黄色框子的解决办法 一、vsCode中文出现黄色框子-如图二、解决办法 一、vsCode中文出现黄色框子-如图 二、解决办法 点击 “文件”点击 “首选项”点击 “设置” 搜索框直接搜索unicode选择“文本编辑器”,往下滑动,找到“Un…...
“可通过HTTP获取远端WWW服务信息”漏洞修复
环境说明:①操作系统:windows server;②nginx:1.27.1。 1.漏洞说明 “可通过HTTP获取远端WWW服务信息”。 修复前,在“响应标头”能看到Server信息,如下图所示: 修复后,“响应标头…...
