UT单元测试
Tips:在使用时一定要注意版本适配性问题
一、Mockito
1.1 Mock的使用
Mock 的中文译为仿制的,模拟的,虚假的。对于测试框架来说,即构造出一个模拟/虚假的对象,使我们的测试能顺利进行下去。

Mock 测试就是在测试过程中,对于某些 不容易构造(如 HttpServletRequest 必须在 Servlet 容器中才能构造出来)或者不容易获取 比较复杂 的对象(如 JDBC 中的 ResultSet对象),用一个 虚拟 的对象(Mock 对象)来创建,以便测试方法。
@Mock 注解用于创建模拟对象,而 @InjectMocks 注解用于注入依赖的模拟对象或真实对象到测试对象中。通常情况下,@Mock 和 @InjectMocks 会配合使用,在单元测试中提供模拟对象和被测试对象之间的依赖关系。
public class BookService {private BookRepository bookRepository;public BookService(BookRepository bookRepository) {this.bookRepository = bookRepository;}public Book findBook(String id) {return bookRepository.findById(id);}
}@ExtendWith(MockitoExtension.class)
class BookServiceTest {@Mockprivate BookRepository bookRepository;@InjectMocksprivate BookService bookService;@Testvoid findBook() {Book book = new Book("1", "Title");when(bookRepository.findById("1")).thenReturn(book);bookService.findBook("1");verify(bookRepository, times(1)).findById("1");}
}
创建了一个模拟的 BookRepository,并且使用了 @InjectMocks 将它注入到了 BookService 的实例中。
1.2 @Mock @Spy @InjectMocks
@Mock:创建一个模拟对象(mocked object)。对其进行设置后,@Mock创建的对象会返回设置好的值而不是执行真实的逻辑。@Spy:创建一个间谍对象(spied object)。它和真实的对象很类似,除非明确设定,否则都是调用真实的方法。@InjectMocks:创建一个实例,其余用@Mock(或@Spy)注解创建的mock会被注入到用@InjectMocks注解的类中。
Q1:既然@spy调用的是真实方法,那我为什么要使用这个注解呢,我直接在需要模拟的方法时候使用mock不就可以了吗
A:@Spy是在你只想模拟类的部分行为,而其他方法还希望执行真实的逻辑时非常有用的。
@Spy
List<String> spyList = new ArrayList<String>();@Test
public void testSpy() {spyList.add("one");spyList.add("two");// 在spy对象上设定返回预期值Mockito.doReturn(100).when(spyList).size();assertEquals(100, spyList.size());assertEquals("one", spyList.get(0));
}
1.3 @mockbean与@SpyBean
@MockBean和@SpyBean是 Spring Boot 测试中常用的两个注解。下面是它们各自的特性:
@MockBean
@MockBean用于在 Spring 上下文中创建一个 Mock 对象,用它替换任何同类型的原有 Bean。@MockBean创建的mock对象没有任何实际行为,只返回预设的值。- 使用
@MockBean,你可以设置对其进行调用的各个方法的预期返回值。
@SpyBean
@SpyBean用于在 Spring 上下文中创建一个 Spy 对象,用它替换任何同类型的原有的 Bean。@SpyBean创建的 spy 对象基于实际的 Bean,事实上它就是原有 Bean 的一个复制体。除非明确地设定,否则它的方法调用结果与原有 Bean 完全相同。- 使用
@SpyBean,你可以监视(或跟踪)Bean 的行为,并能在需要时们改变某些方法的行为。
总的来说,@MockBean 和 @SpyBean 的核心区别是:@MockBean 创建的是一个可配置的纯 mock 对象,而 @SpyBean 则是基于一个实际对象的副本,这个副本中的方法调用能够反映出原有对象的行为。
使用场景:
@MockBean使用场景和代码示例
使用场景:我们通常在Spring的集成测试中使用
@MockBean,这个注解用于替换Spring应用程序上下文中的现有Bean。它创建了一个Mock实例,并使用它替换原本的Bean。@SpyBean使用场景和代码示例
使用场景:当我们希望监测真实的Bean时,我们使用
@SpyBean。一个 Spy Bean 是一个代理,在这个代理中,被Spy的Bean的所有方法都会像平常一样被调用,除非我们明确地改变它们的行为。
1.4 verify的使用方法及场景
Mockito.verify() 方法是 Mockito 框架中用于验证 mock 对象方法调用的工具。通过 verify() 方法,我们可以检查 mock 对象的某个方法是否被调用了,并可以进一步验证调用次数、调用顺序、传入参数等情况。
下面是 Mockito.verify() 方法的基本使用方法及一些常见应用场景:
验证方法是否被调用:
// 创建 mock 对象
List<String> mockList = Mockito.mock(List.class);// 调用被测试的方法
mockList.add("test");// 验证方法 add 是否被调用过一次
Mockito.verify(mockList).add("test");
这两个方法里面的参数必须一样才能进行验证。如果你要验证的方法参数与实际调用的方法参数不一样,那么 Mockito.verify() 方法会抛出异常并提示参数不匹配。
验证方法被调用次数:
// 验证方法 add 被调用了两次
Mockito.verify(mockList, Mockito.times(2)).add("test");
验证方法未被调用:
// 验证方法 add 未被调用
Mockito.verify(mockList, Mockito.never()).add("test");
验证方法在特定顺序下被调用:
// 模拟方法调用
InOrder inOrder = Mockito.inOrder(mockList);
inOrder.verify(mockList).add("first");
inOrder.verify(mockList).add("second");
验证方法传入参数:
// 验证方法 add 是否被调用,并且传入参数为字符串 "hello"
Mockito.verify(mockList).add(Mockito.eq("hello"));
验证方法在特定时间内被调用:
// 验证方法 add 在100ms内是否被调用
Mockito.verify(mockList, Mockito.timeout(100)).add("test");
二、Junit5注解及断言
2.1 Junit5内置注解

2.2 junit5内置断言

三、Mockito 和 PowerMock的差异对比
Mockito 和 PowerMock 是两种广泛使用的 Java 单元测试模拟框架。它们都提供了创建和管理 mock 对象的能力,以帮助我们隔离并测试代码。然而,它们各自的特性使得它们在特定的场景中更有效。
Mockito 特性:
- 是目前最流行的 mocking 框架。
- 它能实现对方法的调用进行模拟,并验证方法的调用情况,通过一种优雅且简洁的 API 来提供这种功能。
- Mockito 不支持 mock 私有,静态和 fianl 方法或类的模拟。
- Mockito 的语法简单且易于阅读,代码可维护性更高。
- Mockito 更关注于“测试行为”,而非“测试结果”。
PowerMock 特性:
- PowerMock 是 Mockito 和 EasyMock 的扩展,它能够模拟更加复杂的场景,包括静态方法,构造器,final 类及方法,私有方法等。
- PowerMock 使用字节码操作技术,通过在运行时修改字节码的方式实现这些复杂的模拟。
- PowerMock 能够执行更深层次的测试,但复杂的特性可能导致代码难以阅读和维护。
- PowerMock 适合用来模拟那些传统上被视为不可模拟的代码。
两者的主要使用场景:
- Mockito 适合用于大多数标准的模拟情况,可以覆盖大部分的日常测试需求。其简单、易读的 API 使其成为首选工具。
- PowerMock 的使用场景则更为具体,如必须模拟静态方法、final 类/方法或私有方法等情况。不过使用 PowerMock 应慎重,这些能力常常提示代码设计存在问题。
使用powerMock模拟mock静态方法
public class UtilityClass {static int staticMethod(long value) {return 100;}
}@RunWith(PowerMockRunner.class)
@PrepareForTest(UtilityClass.class)
public class MockingStaticMethodTest {@Testpublic void testMockingStaticMethod() {//模拟整个 UtilityClass 类PowerMockito.mockStatic(UtilityClass.class);//设置预期返回PowerMockito.when(UtilityClass.staticMethod(5)).thenReturn(10);//在你的测试代码里, 当 UtilityClass.staticMethod(5) 被调用时, 它现在将返回 10int result = UtilityClass.staticMethod(5);assertEquals(10, result);//最后验证静态方法是否被调用PowerMockito.verifyStatic(UtilityClass.class);UtilityClass.staticMethod(5);}
}

相关文章:
UT单元测试
Tips:在使用时一定要注意版本适配性问题 一、Mockito 1.1 Mock的使用 Mock 的中文译为仿制的,模拟的,虚假的。对于测试框架来说,即构造出一个模拟/虚假的对象,使我们的测试能顺利进行下去。 Mock 测试就是在测试过程…...
leetcode-合并两个有序链表
目录 题目 图解 方法一 方法二 代码(解析在注释中) 方法一 编辑方法二 题目 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1: 输入:l1 [1,2,4], l2 [1,3,4] 输出:[1,1…...
006Node.js cnpm的安装
百度搜索 cnpm,进入npmmirror 镜像站https://npmmirror.com/ cmd窗口输入 npm install -g cnpm --registryhttps://registry.npmmirror.com...
web server apache tomcat11-01-官方文档入门介绍
前言 整理这个官方翻译的系列,原因是网上大部分的 tomcat 版本比较旧,此版本为 v11 最新的版本。 开源项目 同时也为从零手写实现 tomcat 提供一些基础和特性的思路。 minicat 别称【嗅虎】心有猛虎,轻嗅蔷薇。 系列文章 web server apac…...
java的总结
由于最近已经开始做项目了,所以对java的基础知识的学习都是一个离散化的状态没有一个很系统的学习,都是哪里不会就去学哪里。 先来讲一下前后端的区别吧 在我的理解前端就是:客户端在前端进行点击输入数据,前端将这些数据整合起来…...
解决npm run dev跑项目,发现node版本不匹配,怎么跑起来?【已解决】
首先问题点就是我们npm run dev 运行项目的时候发现出错,跑不起来,类型下面这种 这里的出错的原因在于我们的node版本跟项目的版本不匹配 解决办法 我这里的问题是我的版本是node14的,然后项目需要node20的,执行下面的就可以正…...
flood_fill 算法|图形渲染
flood fill 算法常常用来找极大连通子图,这是必须掌握的基本算法之一! 图形渲染 算法原理 我们可以利用DFS遍历数组把首个数组的值记为color,然后上下左右四个方向遍历二维数组数组如果其他方块的值不等于color 或者越界就剪枝 return 代码…...
Promise简单概述
一. Promise是什么? 理解 1.抽象表达: Promise是一门新的技术(ES6规范) Promise是JS中进行异步编程的新解决方案(旧方案是单纯使用回调函数) 异步编程:包括fs文件操作,数据库操作(Mysql),AJAX,定时器 2.具…...
【Java集合进阶】数据结构(平衡二又树旋转机制)数据结构(红黑树、红黑规则、添加节点处理方案详解)
🍬 博主介绍👨🎓 博主介绍:大家好,我是 hacker-routing ,很高兴认识大家~ ✨主攻领域:【渗透领域】【应急响应】 【Java】 【VulnHub靶场复现】【面试分析】 🎉点赞➕评论➕收藏 …...
富文本在线编辑器 - tinymce
tinymce 项目是一个比较好的富文本编辑器. 这里有个小demo, 下载下来尝试一下, 需要配置个本地服务器才能够访问, 我这里使用的nginx, 下面是我的整个操作过程: git clone gitgitee.com:chick1993/layui-tinymce.git cd layui-tinymcewget http://nginx.org/download/nginx-1.…...
从汇编代码理解数组越界访问漏洞
数组越界访问漏洞是 C/C 语言中常见的缺陷,它发生在程序尝试访问数组元素时未正确验证索引是否在有效范围内。通常情况下,数组的索引从0开始,到数组长度减1结束。如果程序尝试访问小于0或大于等于数组长度的索引位置,就会导致数组…...
skynet 使用protobuf
一、安装protobuf 下面的操作方法都是在 centos 环境下操作 #下载 Protocol Buffers 源代码: #您可以从 Protocol Buffers 的 GitHub 仓库中获取特定版本的源代码。使用以下命令克隆仓库 git clone -b v3.20.3 https://github.com/protocolbuffers/protobuf.git#编译…...
Vue Router 4 与 Router 3 路由配置与区别
文章目录 路由安装路由配置vue-router 3.x版本写法配置路由使用路由 vue-router 4.x版本写法配置路由使用路由 Vue Router 4 与 Vue Router 3 区别 路由安装 Vue 2 (使用 Vue Router 3) :npm install vue-router3 Vue 3 (使用 Vue Router 4) :npm insta…...
python借助elasticsearch实现标签匹配计数
给定一组标签 [{“tag_id”: “1”, “value”: “西瓜”}, {“tag_id”: “1”, “value”: “苹果”}],我想精准匹配到现有的标签库中存在的标签并记录匹配成功的数量。 标签id(tag_id)标签名(tag_name)标签值(tag_name )1水果西瓜1水果苹果1水果橙子2动物老虎 …...
Yolo-world+Python-OpenCV之摄像头视频实时目标检测
上一次介绍了如何使用最基本的 Yolo-word来做检测,现在我们在加opencv来做个实时检测的例子 基本思路 1、读取离线视频流 2、将视频帧给yolo识别 3、根据识别结果 对视频进行绘制边框、加文字之类的 完整代码如下: import datetimefrom ultralytics …...
vue-treeselect 的基本使用
vue-treeselect 的基本使用 1. 效果展示2. 安装 插件3. 引入组件4. 代码 1. 效果展示 2. 安装 插件 vue-treeselect是一个树形的下拉菜单,至于到底有多少节点那就要看你的数据源有多少层了,挺方便的。下面这个这个不用多说吧,下载依赖 npm in…...
Vue(二)
文章目录 1.条件渲染1.关于js中的false的判定2.基本介绍3.v-if1.需求分析2.代码实例 4.v-show实现5.v-if与v-show比较6.课后练习 2.列表渲染1.代码实例2.课后练习 3.组件化编程1.基本介绍2.实现方式一_普通方式2.实现方式二_全局组件方式3.实现方式三_局部组件方式 4.生命周期和…...
Python基于深度学习的车辆特征分析系统
博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…...
推理还原的干货
故事的递进还原 从下层故事到上层故事 设定还原 还原的逻辑 隐藏信息拼凑、因果导致果推因、规则还原现象 设计思路: 真解答 真解答的关键信息 推理逻辑链 哪些环节可以被误导 如何把关键信息变成伪解答 解释变形信息 给出识别变形信息的方法或线索 其实看似一个…...
【Redis 神秘大陆】006 灾备方案
六、Redis 灾备方案 6.1 存储方案 6.1.1 基础对比 RDB持久化AOF持久化原理周期性fork子进程生成持久化文件每次写入记录命令日志文件类型二进制dump快照文件文本appendonly日志文件触发条件默认超过300s间隔且有1s内超过1kb数据变更永久性每秒fsync一次文件位置配置文件中指…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
