如何用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. 系统会检查该收藏记录是否存在

  2. 如果不存在则创建新收藏记录

  3. 更新论坛的收藏数(+1)

  4. 返回成功消息

测试覆盖了收藏服务的主要逻辑路径,确保在收藏记录不存在时的正确行为。

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/news/906069.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

最新缺陷检测模型:EPSC-YOLO(YOLOV9改进)

目录 引言:工业缺陷检测的挑战与突破 一、EPSC-YOLO整体架构解析 二、核心模块技术解析 1. EMA多尺度注意力模块:让模型"看得更全面" 2. PyConv金字塔卷积:多尺度特征提取利器 3. CISBA模块:通道-空间注意力再进化 4. Soft-NMS:更智能的重叠框处理 三、实…

【Linux网络与网络编程】12.NAT技术内网穿透代理服务

1. NAT技术 之前我们说到过 IPv4 协议中IP 地址数量不充足的问题可以使用 NAT 技术来解决。还提到过本地主机向公网中的一个服务器发起了一个网络请求&#xff0c;服务器是怎么将应答返回到该本地主机呢&#xff1f;&#xff08;如何进行内网转发&#xff1f;&#xff09; 这就…

uniapp的适配方式

文章目录 前言✅ 一、核心适配方式对比&#x1f4cf; 二、rpx 单位&#xff1a;uni-app 的核心适配机制&#x1f9f1; 三、默认设计稿适配&#xff08;750宽&#xff09;&#x1f501; 四、字体 & 屏幕密度适配&#x1f6e0; 五、特殊平台适配&#xff08;底部安全区、刘海…

JAVA EE(进阶)_进阶的开端

别放弃浸透泪水的昨天&#xff0c;晨光已为明天掀开新篇 ——陳長生. ❀主页&#xff1a;陳長生.-CSDN博客❀ &#x1f4d5;上一篇&#xff1a;JAVA EE_HTTP-CSDN博客 1.什么是Java EE Java EE&#xff08;Java Pla…

SQL脚本规范

主要作用&#xff1a;数据库的备份和迁移 SQL脚本规范 每一个sql语句必须与;结束 脚本结构&#xff1a; { 删库&#xff0c;建库 删表&#xff0c;建表 插入初始数据 } 建库语法&#xff1a; CREATE DATABASE 数据库名CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CHARA…

std::ratio<1,1000> 是什么意思?

author: hjjdebug date: 2025年 05月 14日 星期三 09:45:24 CST description: std::ratio<1,1000> 是什么意思&#xff1f; 文章目录 1. 它是一种数值吗&#xff1f;2. 它是一种类型吗&#xff1f;3. std:ratio 是什么呢&#xff1f;4. 分析一个展开后的模板函数5.小结: …

测试--测试分类 (白盒 黑盒 单元 集成)

一、按照测试目标分类&#xff08;测试目的是什么&#xff09; 主类别细分说明1. 界面测试UI内容完整性、一致性、准确性、友好性&#xff0c;布局排版合理性&#xff0c;控件可用性等2. 功能测试检查软件功能是否符合需求说明书&#xff0c;常用黑盒方法&#xff1a;边界值、…

整理了 2009 - 2025 年的【199 管综真题 + 解析】PDF,全套共 34 份文件

每年真题原卷 ✅ 每年详细解析 ✅ &#x1f4c2;【管综真题 2009-2025】 &#x1f4c2;【管综解析 2009-2025】 目录树&#xff1a; ├── 2009-2025管综真题 PDF │ ├── 2009年199管综真题.pdf │ ├── 2010年199管综真题.pdf │ ├── 2011年199管综真题.pd…

用golang实现二叉搜索树(BST)

目录 一、概念、性质二、二叉搜索树的实现1. 结构2. 查找3. 插入4. 删除5. 中序遍历 中序前驱/后继结点 一、概念、性质 二叉搜索树&#xff08;Binary Search Tree&#xff09;&#xff0c;简写BST&#xff0c;又称为二叉查找树 它满足&#xff1a; 空树是一颗二叉搜索树对…

自动化:批量文件重命名

自动化&#xff1a;批量文件重命名 1、前言 2、效果图 3、源码 一、前言 今天来分享一款好玩的自动化脚&#xff1a;批量文件重命名 有时候呢&#xff0c;你的文件被下载下来文件名都是乱七八糟毫无规律&#xff0c;但是当时你下载的时候没办法重名或者你又不想另存为重新重…

VueUse/Core:提升Vue开发效率的实用工具库

文章目录 引言什么是VueUse/Core&#xff1f;为什么选择VueUse/Core&#xff1f;核心功能详解1. 状态管理2. 元素操作3. 实用工具函数4. 浏览器API封装5. 传感器相关 实战示例&#xff1a;构建一个拖拽上传组件性能优化技巧与原生实现对比常见问题解答总结 引言 在现代前端开发…

stm32 ADC单通道转换

stm32c8t6仅有12位分辨率 1、单次转换 非扫描 1、初始化 void Ad_Init() {RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//配置ADCCLK时钟分频,ADC的输入时钟不得超过14MHzRCC_ADCCLKConfig(RCC_PCLK2_Div6);G…

2KW压缩机驱动参考设计【SCH篇】

实物展示&#xff1a; ACDC: VAC和VAC-为交流电压检测&#xff1a; 1.C33 C34作为Y电容走线宽度要求&#xff1a; Y电容一般用于L/N到地之间&#xff08;L-PE 或 N-PE&#xff09;&#xff0c;主要作用是抑制共模干扰。其走线的电流非常小&#xff0c;推荐使用 ≥ 1mm 宽的走…

python05——循环结构

1、while循环 n0 #初始条件 while n<5: #判断print(hello python) #要重复执行的代码print(n) #注意同级代码缩进相同n1 #计数器结果&#xff1a; hello python 0 hello python 1 hello python 2 hello python 3 hello python 4 hello python 5 #求阶乘和 sum0 n1 whil…

LINUX编译、运行、测试lowcoder_CN

参考 二者没有太大差异。 LINUX编译、运行、测试lowcoder-CSDN博客 下载 git clone https://github.com/mousheng/lowcoder_CN 或 git clone https://gitcode.com/gh_mirrors/lo/lowcoder_CNcd lowcoder_CN三个模块 node-service api-service client 每个模块都有自己的…

Python 基础之函数命名

几个问题 使用描述性蛇形命名法&#xff08;snake_case&#xff09;Python函数名应使用什么大小写格式&#xff1f;为什么函数名要具有描述性&#xff1f;方法的命名规范是什么&#xff1f;函数、变量和类的命名有何区别&#xff1f; Python函数的命名有一些不可违背的硬性规…

redis 命令大全整理

http://doc.redisfans.com/ 原网址 Redis 命令分类 Key(键) Key(键)命令 exists/del/keys/type/scanobject/move/dump/migratettl/pttl/persist/expireat/pexpireat/expire/pexpirerename/renamenxsort/randomkey/restoreexists 语法:exists key [key ...] 检查一个或多…

React中useDeferredValue与useTransition终极对比。

文章目录 前言一、核心差异对比二、代码示例对比1. useDeferredValue&#xff1a;延迟搜索结果更新2. useTransition&#xff1a;延迟路由切换 三、应用场景总结四、注意事项五、原理剖析1. 核心机制对比2. 关键差异3. 代码实现原理 总结 前言 在React的并发模式下&#xff0c…

高并发内存池|定长内存池的设计

二、定长内存池的设计 设计一个定长的内存池&#xff0c;这个内存池的定长在于&#xff0c;当剩余空间使用完毕后&#xff0c;总是开辟相同长度的新空间来使用。我们会使用到一个指针来切割划分大空间为小空间。大空间是内存池向系统申请的内存大小&#xff0c;而小空间是程序…

微信小程序 自定义图片分享-绘制数据图片以及信息文字

一 、需求 从数据库中读取头像&#xff0c;姓名电话等信息&#xff0c;当分享给女朋友时&#xff0c;每个信息不一样 二、实现方案 1、先将数据库中需要的头像姓名信息读取出来加载到data 数据项中 data:{firstName:, // 姓名img:, // 头像shareImage:,// 存储临时图片 } 2…