如何用mockito+junit测试代码
Mockito 是一个流行的 Java 模拟测试框架,用于创建和管理测试中的模拟对象(mock objects)。它可以帮助开发者编写干净、可维护的单元测试,特别是在需要隔离被测组件与其他依赖项时。
目录
核心概念
1. 模拟对象(Mock Objects)
2. 打桩(Stubbing)
3. 验证(Verification)
1. 测试准备
2. 模拟依赖(Mock)
3. 执行测试
4. 验证结果
5. 验证收藏数增加
总结
核心概念
1. 模拟对象(Mock Objects)
模拟对象是真实对象的替代品,用于在测试中模拟真实对象的行为,而不需要实际调用真实对象。
2. 打桩(Stubbing)
定义模拟对象在特定条件下的行为,即当调用某个方法时返回什么值或抛出什么异常。
3. 验证(Verification)
验证模拟对象的特定方法是否被调用,以及调用的次数和参数是否符合预期。
下面进行实际操作
等待测试的源码:
@Overridepublic JSONReturn save(Collect collect) {Collect exist = collectMapper.selectExist(collect.getUserId(),collect.getForumId());if(exist != null){return JSONReturn.failed("操作失败,您已收藏该帖子!");}Date date = new Date();collect.setCreateTime(date);collect.setUpdateTime(date);collectMapper.insert(collect);
// //收藏+1Forum forum = forumMapper.selectByPrimaryKey(collect.getForumId());forum.setCollectNum(forum.getCollectNum() + 1);forumMapper.updateByPrimaryKeySelective(forum);return JSONReturn.success("收藏成功!");}
以下下是mock的代码
@Testvoid save_shouldReturnSuccess_whenCollectNotExists() {Collect collect = new Collect();collect.setUserId(2);collect.setForumId(9);when(collectMapper.selectExist(2, 9)).thenReturn(null); Forum forum = new Forum();forum.setCollectNum(0);when(forumMapper.selectByPrimaryKey(9)).thenReturn(forum);JSONReturn result = collectService.save(collect);assertEquals("收藏成功!", result.getMsg()); // Should return success messageverify(collectMapper, times(1)).selectExist(2, 9);verify(collectMapper, times(1)).insert(collect);verify(forumMapper, times(1)).updateByPrimaryKeySelective(any(Forum.class));ArgumentCaptor<Forum> forumCaptor = ArgumentCaptor.forClass(Forum.class);verify(forumMapper).updateByPrimaryKeySelective(forumCaptor.capture());Integer collectNum = forumCaptor.getValue().getCollectNum();assertEquals(new Integer(1), collectNum);}
这是一个单元测试方法,测试当收藏记录不存在时成功保存收藏的功能。下面是对代码的逐步解释:
1. 测试准备
Collect collect = new Collect();
collect.setUserId(2);
collect.setForumId(9);
创建一个新的收藏对象,设置用户ID为2,论坛ID为9。
2. 模拟依赖(Mock)
when(collectMapper.selectExist(2, 9)).thenReturn(null);
模拟collectMapper.selectExist(2, 9)
方法调用,返回null表示该收藏记录不存在。
Forum forum = new Forum();
forum.setCollectNum(0);
when(forumMapper.selectByPrimaryKey(9)).thenReturn(forum);
创建一个论坛对象,设置收藏数为0,并模拟forumMapper.selectByPrimaryKey(9)
返回这个论坛对象。
3. 执行测试
JSONReturn result = collectService.save(collect);
调用被测试的collectService.save()
方法。
4. 验证结果
assertEquals("收藏成功!", result.getMsg());
验证返回的消息是"收藏成功!"。
verify(collectMapper, times(1)).selectExist(2, 9);
verify(collectMapper, times(1)).insert(collect);
验证:
-
selectExist
方法被调用了一次 -
insert
方法被调用了一次
verify(forumMapper, times(1)).updateByPrimaryKeySelective(any(Forum.class));
验证updateByPrimaryKeySelective
方法被调用了一次。
5. 验证收藏数增加
ArgumentCaptor<Forum> forumCaptor = ArgumentCaptor.forClass(Forum.class);
verify(forumMapper).updateByPrimaryKeySelective(forumCaptor.capture());
Integer collectNum = forumCaptor.getValue().getCollectNum();
assertEquals(new Integer(1), collectNum);
使用ArgumentCaptor
捕获传递给updateByPrimaryKeySelective
的Forum对象,验证其收藏数从0增加到了1。
总结
这个测试验证了当用户收藏一个尚未收藏的论坛时:
-
系统会检查该收藏记录是否存在
-
如果不存在则创建新收藏记录
-
更新论坛的收藏数(+1)
-
返回成功消息
测试覆盖了收藏服务的主要逻辑路径,确保在收藏记录不存在时的正确行为。
相关文章:
如何用mockito+junit测试代码
Mockito 是一个流行的 Java 模拟测试框架,用于创建和管理测试中的模拟对象(mock objects)。它可以帮助开发者编写干净、可维护的单元测试,特别是在需要隔离被测组件与其他依赖项时。 目录 核心概念 1. 模拟对象(Mock Objects) 2. 打桩(Stubbing) 3. 验…...
31、魔法生物图鉴——React 19 Web Workers
一、守护神协议(核心原理) 1. 灵魂分裂术(线程架构) // 主组件中初始化Workerconst workerRef useRef(null);useEffect(() > {workerRef.current new Worker(new URL(./creatureWorker.js, import.meta.url));workerRef.…...
洛谷题目:P4052 [JSOI2007] 文本生成器 题解 本题(极难)
个人介绍: 题目传送门: P4052 [JSOI2007] 文本生成器 - 洛谷 (luogu.com.cn) 前言: 这道题要求计算长度为 m 的文章中,至少包含一个给定单词的可读文章的数量,并且结果需要对 10007 取模。下面是小亦为大家逐步分析解题思路: 题目整体思路: 为了方便计算…...
【Linux】命令行参数和环境变量
目录 一、命令行参数 二、环境变量 (一)PATH (二)查看环境变量 (三)获取环境环境变量 (四)为什么要环境变量 (五)环境变量特点总结 (1&am…...
AGI大模型(23):LangChain框架快速入门之LangChain介绍
1 什么是LangChain? LangChain是一个基于大语言模型用于构建端到端语言模型应用的框架,它提供了一系列工具、套件和接口,让开发者使用语言模型来实现各种复杂的任务,如文本到图像的生成、文档问答、聊天机器人等。 官网地址:https://python.langchain.com/docs/introduc…...
vmware虚拟机运行多个产生卡顿问题
最近在工作中使用电脑运行两个虚拟机,用来测试程序。运行的时候发现电脑会非常卡顿。导致调试工作进行到一半就会闪退卡死。 首先尝试的解决方案是开一个虚拟机,然后在windows上部署测试程序,后面发现操作很受限制。然后使用windows管…...
八股碎碎念01——HashMap原理
Java面试题周总结 HashMap HashMap实现原理 Java 1.7版本 在Java1.7中HashMap通过数组链表的方式实现,由于链表查询速度为O(n),因此在插入大量元素后查询速度会明显降低。 Java 1.8版本 在Java1.8中对HashMap进行改进,采用数组链表/红黑…...
长篇小说《白鹿原》原著版本在当当网可购到
著名作家陈忠实所真实描写上世纪1959年、1960年、1961年我国三年饥荒时人吃人的长篇小说《白鹿原》原著版本,现能在当当网上购到,价格仅26元。特此推荐。 笔者是从那段不堪回首的饥饿历史中幸存下来的过来人,也是在改革开放初期的文艺复兴年代…...
ColorAid —— 一个面向设计师的色盲模拟工具开发记
我正在参加CodeBuddy「首席试玩官」内容创作大赛,本文所使用的 CodeBuddy 免费下载链接:腾讯云代码助手 CodeBuddy - AI 时代的智能编程伙伴 起因:CodeBuddy,说干就干 起初只是一个随口的想法——我想做一个“色盲辅助工具”&…...
对称加密与非对称加密在 JWT 中的应用详解
文章目录 对称加密与非对称加密在 JWT 中的应用详解引言对称加密与非对称加密概述对称加密(Symmetric Encryption)非对称加密(Asymmetric Encryption) 对称加密生成和验证 JWT 的过程生成 JWT(HS256 示例)验…...
Python 中 if 和 else 基础知识的详解和使用
一、基本语法结构 if 条件1:# 条件1 为真时执行的代码块 elif 条件2:# 条件1 不成立,条件2 成立时执行 else:# 所有条件都不成立时执行注意: elif 是“else if”的缩写,可以有多个;else 可省略;条件表达式必须是可以…...
学习黑客Active Directory 入门指南(三)
Active Directory 入门指南(三):关键服务、用户与组管理 🤝💻 大家好!欢迎来到 “Active Directory 入门指南” 系列的第三篇。在前两篇中,我们已经了解了AD的基本概念、逻辑结构(对…...
10.9 LangChain LCEL革命:43%性能提升+声明式语法,AI开发效率飙升实战指南
LangChain 表达式语言(LCEL)架构解析:新一代链式编排引擎 关键词:LangChain Expression Language, Runnable 协议, 链式编排, 并行处理, 生产级应用开发 1. LCEL 设计理念与技术突破 LangChain Expression Language(LCEL)是 LangChain v0.3 的核心革命性升级,重新定义…...
一文读懂-嵌入式Ubuntu平台
现在直接在一些嵌入式Soc上移植ubuntu来用到产品上,刚开始感觉还挺臃肿的,后来细聊了下感觉还是有一定的优势。 ubuntu相信大家在熟悉不过了,几乎无处不在,小到咖啡机,大到火星车,为什么ubuntu如此广泛&am…...
centos7.9扩展已有分区空间
新增50G硬盘 分区 fdisk /dev/sdb Command (m for help): p #打印分区表Disk /dev/sdb: 53.7 GB, 53687091200 bytes, 104857600 sectors Units sectors of 1 * 512 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 byte…...
ubuntu22.04搭建ROS2环境
在 Ubuntu 22.04 上安装 ROS 2(Humble Hawksbill)时,针对国内网络问题,建议使用镜像源加速。以下是分步指南: 1. 更换 Ubuntu 系统源(使用清华镜像) sudo sed -i "shttp://.*archive.ubunt…...
java中sleep()和wait()暂停线程的区别
1. Thread.sleep() 所属类:它是Thread类的静态方法。作用:让当前正在执行的线程暂停指定的时间,在暂停期间,线程会一直持有对象锁(也就是synchronized锁)。中断响应:当线程处于sleep()状态时&a…...
printf函数参数与入栈顺序
01. printf()的核心功能 作用:将 格式化数据 输出到 标准输出(stdout),支持多种数据类型和格式控制。 int printf(const char *format, ...);参数: format:格式字符串,字符串或%开头格式符...:…...
代码案例分析
以下是一个使用线性回归进行简单房价预测的机器学习代码案例分析: 代码示例 import numpy as np import matplotlib.pyplot as plt from sklearn.linear_model import LinearRegression from sklearn.model_selection import train_test_split # 生成一些示例数据…...
Baklib赋能企业知识资产AI化升级
AI驱动知识管理革新 在数字化转型浪潮中,企业知识管理的范式正经历AI技术的深度重构。传统知识库受限于静态存储与人工维护,而Baklib通过构建知识中台架构,将多模态数据处理与语义理解引擎深度融合,实现知识资产的动态聚合与智能…...
Leetcode 3552. Grid Teleportation Traversal
Leetcode 3552. Grid Teleportation Traversal 1. 解题思路2. 代码实现 题目链接:3552. Grid Teleportation Traversal 1. 解题思路 这一题的话核心就是一个广度优先遍历,我们只需要从原点开始,一点点考察其所能到达的位置,直至…...
【Bluedroid】蓝牙HID DEVICE 报告发送与电源管理源码解析
本文基于Android蓝牙协议栈代码,深度解析HID设备(如键盘、鼠标)从应用层发送输入报告到主机设备的完整流程,涵盖数据封装、通道选择、L2CAP传输、电源管理四大核心模块。通过函数调用链(send_report → BTA_HdSendRepo…...
day15-进程管理
1. 概述 运行起来的软件就是进程,在内存中运行守护进程/服务:一直运行的进程 2. 僵尸进程 2.1. 僵尸进程zombie 当子进程比父进程先结束,而父进程又没有回收子进程,释放子进程占用的资源,此时子进程将成为一个僵尸…...
抖音视频下载工具 v1.1 自用分享
用免费的公益接口用AI写了个简单的抖音视频下载工具,自用的,不支持批量下载 内置两套API,解析失败会自动切换,支持视频预览播放,视频截图等操作 使用方法也很简单: 软件打开后会监听粘贴板,当检…...
46、什么是Windows服务,它的⽣命周期与标准的EXE程序有什么不同?
Windows服务是一种在Windows操作系统后台运行的特殊应用程序,与标准的EXE程序相比,其生命周期在启动方式、运行持续性、用户交互、运行账户、管理方式、进程状态及开发要求等方面存在显著差异。以下是对Windows服务及其与标准EXE程序生命周期差异的详细分…...
用 UniApp 构建习惯打卡 App —— HabitLoop 开发记
我正在参加CodeBuddy「首席试玩官」内容创作大赛,本文所使用的 CodeBuddy 免费下载链接:腾讯云代码助手 CodeBuddy - AI 时代的智能编程伙伴 当我脑海中突然冒出一个念头:“做一个自己能每天打卡的习惯 App 吧”,我立刻打开了 Cod…...
NB-IoT技术深度解析:部署模式与节能机制全指南
知识点1【NB-IoT的介绍】 NB-IoT 是指Narrow Band Internet of Things,聚集于低功耗窄带宽广域物联网。 1、License介绍 “有牌照”(license)频谱,指的是政府或者监管机构通过拍卖,划拨等方式,授予给各个…...
Vue百日学习计划Day28-32天详细计划-Gemini版
总目标: 在 Day 28-32 深入理解 Vue 3 的响应式机制,熟练掌握 Composition API 中的 setup, ref, reactive, toRefs, readonly, computed, watch, watchEffect 等核心 API 的使用。 所需资源: Vue 3 官方文档 (组合式 API): https://cn.vuejs.org/guide/introducti…...
Leetcode134加油站
题目链接 134 题意图解: 题目给了n个节点,这些节点呈现环状,每次到一个低点要消耗cost[i]的油量。 从中我们可以得出一个结论:看一个点能不能到下一个点,就要用当前的油量减去消耗的量,那么gas[i] - cost…...
用算术右移实现逻辑右移及用逻辑右移实现算术右移
函数srl()用算术右移实现逻辑右移,函数sra()用逻辑右移实现算术右移。 程序代码 int sra(int x,int k); unsigned int srl(unsigned int x, int k);void main() {int rx1,k,x1;unsigned int rx2,x2;k3;x10x8777;x20x8777;rx1sra(x1, k);rx2srl(x2, k);while(1); }…...
箭头函数及其与普通函数区别的详细解释
一、箭头函数的基本特性 语法简洁性 箭头函数使用 > 符号定义,省略 function 关键字,适合快速定义匿名函数或简单表达式。 // 普通函数 function sum(a, b) { return a b; } // 箭头函数 const sum (a, b) > a b;若函数体为单行表达式&#x…...
Denoising Score Matching with Langevin Dynamics
在自然图像等复杂数据集中,真实数据往往集中分布在一个低维流形上,概率密度函数的梯度(即得分函数)难以定义与估计。为缓解该问题,SMLD 提出使用不同强度的高斯噪声对数据进行扰动,扰动后的数据不再集中于低…...
Flink的时间问题
Apache Flink 中的 时间语义(Time Semantics) 是流处理的核心概念之一。Flink 支持多种时间类型,用于控制窗口计算、事件排序和状态管理等操作。 🕒 一、Flink 时间分类 类型名称描述Processing Time处理时间每个算子基于本地系统…...
3:OpenCV—视频播放
播放来自文件或相机的视频 在本教程中,我将向您展示如何使用OpenCV从文件或相机/网络摄像头捕获和播放视频。尽管OpenCV没有针对视频处理进行优化,但它提供了一个简单的API来播放视频。在我们的OpenCV程序中,我们所要做的就是从视频文件或相…...
AI工程 新技术追踪 探讨
文章目录 一、核心差异维度对比二、GitHub对AI工程师的独特价值三、需要警惕的陷阱四、推荐追踪策略五、与传统开发的平衡建议 以下内容整理来自 deepseek 作为AI工程师,追踪GitHub开源项目 对技术成长和职业发展的影响 比传统应用开发工程师 更为显著,…...
C++:函数模板
所谓函数模板就是定义一个通用的函数,不指定具体的参数,用一个虚拟参数代替; 当函数调用时,会根据实参判断具体的类型。 注意:不要使用默认参数;可以重载但尽量不要重载。 #include<iostream> usi…...
一款适配国内的视频软件,畅享大屏与局域网播放
软件介绍 今天要给大家安利一款超强视频播放软件——MXPlayer。它的解码实力堪称一绝,市面上不管是常见的 MP4、MKV 格式,还是对播放设备要求极高的超高清 4K、HDR 视频,甚至那些鲜为人知的冷门格式,它统统都能流畅播放ÿ…...
SONiC系统之高速数据遥测High Frequency Telemetry
SONiC系统之高速数据遥测High Frequency Telemetry 数据遥测 这篇文章介绍了SONiC系统支持Telemetry的软件架构以及gNMI接口中Telemetry Streaming功能Dial-in和Dial-out两者模式的区别。正如该文指出的那样,该结构面临扩展性问题,当AI训练、推理等大型…...
【Java ee初阶】jvm(3)
一、双亲委派机制(类加载机制中,最经常考到的问题) 类加载的第一个环节中,根据类的全限定类名(包名类名)找到对应的.class文件的过程。 JVM中进行类加载的操作,需要以来内部的模块“类加载器”…...
C++ for QWidget:connect(连接)
语法: QObject::connect(发射信号的对象,发射的信号,接收信号的对象,接收后执行的命令) #include "mainwindow.h" #include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) {ui-&g…...
uni-app学习笔记七-vue3事件处理
本文主要用于记录vue3中的点击事件和change事件 点击事件:v-on:click,可简写为click change事件,用于监听值发生改变的的事件处理:change 示例代码: <template><view class"box" click"onClick"…...
【C++进阶篇】C++容器完全指南:掌握set和map的使用,提升编码效率
C容器的实践与应用:轻松掌握set、map与multimap的区别与用法 一. 序列式容器与关联式容器1.1 序列式容器 (Sequential Containers)1.2 关联式容器 (Associative Containers) 二. set系列使用2.1 set的构造和迭代器2.2 set的增删查2.2.1 插入2.2.2 查找2.2.3 删除 2.…...
吴恩达机器学习(1)——机器学习算法分类
1、机器学习算法 1、监督学习 在实际应用中最为常见的快速进度结果 2、非监督学习 2、监督学习(Supervised Learning) 2.1、回归算法 [!note] 监督学习 是指学习从 x -> y 或者从输入到输出映射的算法 监督学习的关键特征是你给学习算法提供学习…...
我的创作纪念日——512天
2023 年 12 月 19 日,我撰写了第 1 篇记录型博客《数据结构课程设计——报数问题》,这是我记录一段实践经验的开始。 回望那时的自己,还很稚嫩,刚刚迈入计算机的大门不久,一切都显得新鲜而充满挑战。今天是我成为创作者…...
SpringBoot快速上手
1.Maven Maven是项目管理工具,通过pom.xml文件来获取jar包,而不用手动去添加jar包 引入依赖之后需要刷新maven,以下这两个地方都可以 中央仓库 : Central Repository: Maven Repository: Central 2.Spring Boot 2.1创建项目…...
自动化:批量文件重命名
自动化:批量文件重命名 1、前言 2、效果图 3、源码 一、前言 今天来分享一款好玩的自动化脚:批量文件重命名 有时候呢,你的文件被下载下来文件名都是乱七八糟毫无规律,但是当时你下载的时候没办法重名或者你又不想另存为重新重…...
低延迟与高性能的技术优势解析:SmartPlayer VS VLC Media Player
在实时视频流的应用中,RTSP(Real-Time Streaming Protocol)播放器扮演着至关重要的角色,尤其是在视频监控、远程医疗、直播等高实时性需求的场景中。随着行业需求的不断升级,对播放器的低延迟、稳定性、兼容性等方面的…...
java中的Servlet2.x详解
一、Servlet 2.x 版本演进与核心特性 Servlet 2.x 是 Java Web 开发中承上启下的重要版本系列,主要包括 Servlet 2.4 和 Servlet 2.5 两个子版本。以下是其核心特性与改进: Servlet 2.4(2003年发布) XML Schema 支持:…...
大模型deepseek如何助力数据安全管理
敏感数据识别与处理 精准定位敏感信息 :运用多模态识别引擎技术,快速扫描上传文件与输入内容,精准识别身份证号、银行卡号、商业合同关键信息等各类敏感数据,并支持金融、医疗等行业定制化规则库,满足不同行业的特殊需…...
【linux驱动】【设备树】按键设备树讲解
设备树你添加电源键示例。 / {gpio-keys {compatible = "gpio-keys";#address-cells = <1>;#size-cells = <0>;button@1 {label = "Power Button";linux,code = <KEY_POWER>; // 按键编码,定义在include/uapi/linux/input-event-code…...