【SpringBoot】单元测试实战演示及心得分享
目录1.指定测试标准2.设计测试用例3.测试集示例4.跑测试集1.指定测试标准单元测试会用到mock和junit的内容作者前文有详解可移步Spring Boot单元测试-CSDN博客mockito的详细使用-CSDN博客1.1.测哪一层以当前后端标准的MVC分层来说后端代码分为controller、service、dao三层。首先我们要先确定这三层里面去测试哪一层单元测试的核心目的是什么覆盖业务代码按标准的来说的话controller层是系统对外暴露的API这一层级只负责做一些请求和参数的处理service层用来编写具体的业务逻辑dao层负责与数据库进行交互。所以我们应该测service层。1.2.如何判断测试是否通过测试的输出结果和我们期望的输出结果是一致的测试就通过了。怎么判断喃用Assert断言Assert不要到处去用在测试用例的最后用它来判断一下输出结果是不是期望值即可。1.3.mock掉哪些内容mock我们主要拿来干两件事儿mock掉对数据库的操作避免引起数据的改动也就是说要mock掉dao层的方法mock掉没办法达到的地方比如有些地方不影响代码逻辑但是在测试的时候不好造出来这些不可达的地方可以mock掉。mock我们要mock两种情况mock返回值mock行为mock返回值比如Train train new Train(); String id UUID.randomUUID() ; train.setKeyId(id); when(trainDao.getDetail(any(Train.class))).thenReturn(train);mock行为有些时候是主动的我们想去定义实体的具体行为有时候是被动的比如要mock的dao方法没有返回值该我们就只能通过去mock行为来使得它不去操作数据库反正核心就是不让它去操作数据库。比如以下方法void trainDetailDao.updateList(XXX)用doAnswer去mock它的响应Test public void modifyTrainDetails(){ ? TrainDetailList trainDetails new TrainDetailList(); ? TrainDetail trainDetail new TrainDetail(); ? trainDetail.setKeyId(UUID.randomUUID()); ? trainDetails.add(trainDetail); ? doAnswer(invocation - { ? ? ? ListTrainDetail trainDetailList (ListTrainDetail) invocation.getArguments()[0]; ? ? ? Assert.assertEquals(trainDetails.getItems(), trainDetailList); ? ? ? return trainDetails; ? }).when(trainDetailDao).updateList(any()); ? trainDetailBaseSvr.modifyTrainDetails(,trainDetails); }2.设计测试用例一个接口只需要一个测试用例吗有时候是不够的。衡量对一个接口的单元测试是不是到位了核心指标是看它的分支覆盖率。代码种的一个方法里面有些时候会存在一些选择分支带判断性质的语句我们设计测试用例的时候要考虑覆盖掉所有分支。最好的办法就是画个流程图设计测试用例的时候要覆盖掉所有流程分支以下以用户买猪肉为一个例子灰色的节点就是要mock掉的细化成流程图流程图的所有出口就是要覆盖的分支有几个出口就应该有几个用例有几个测试方法3.测试集示例以下是作者在工作中编写的一个测试集用例演示了一个简单的对增删改查方法的覆盖。里面演示了如何覆盖有返回值的方法和没有返回值的方法。这里有几个技巧分享一下首先是要mock掉dao层的话我们就要把service里面依赖的dao换成mock出来的dao这里需要用反射的方式强行访问到service里面的dao然后把它替换掉。其次mock掉dao层之后直接new service就行完全不需要用到自动注入也就是不需要用到IOC也就不需要用到RunWith(XXX.class) SpringBootTest(classes XXX.class)之类的注解来启动SpringBoot了。这样跑测试用例的时候省去了启动时间会快很多。public class ExaminationBaseSvrTest extends PropertyControllerBase { IExaminationBaseSvr examinationBaseSvr; ExaminationTargetService examinationTargetService; private ExaminationDao examinationDao; private IDataDicItemBaseMgeSvr dataDicItemBaseMgeSvr; private DataDictionaryItemDao dataDictionaryItemDao; Before public void setUp() throws Exception{ examinationBaseSvr new ExaminationBaseSvr(); Field field ExaminationBaseSvr.class.getDeclaredField(examinationDao); Field dataDicItemBaseMgeSvrField ExaminationBaseSvr.class.getDeclaredField(dataDicItemBaseMgeSvr); Field dataDictionaryItemDaoField DataDicItemBaseMgeSvr.class.getDeclaredField(dataDictionaryItemDao); field.setAccessible(true); dataDicItemBaseMgeSvrField.setAccessible(true); dataDictionaryItemDaoField.setAccessible(true); examinationDao mock(ExaminationDao.class); dataDictionaryItemDaomock(DataDictionaryItemDao.class); dataDicItemBaseMgeSvrmock(DataDicItemBaseMgeSvr.class); field.set(examinationBaseSvr, examinationDao); dataDicItemBaseMgeSvrField.set(examinationBaseSvr,dataDicItemBaseMgeSvr); dataDictionaryItemDaoField.set(dataDicItemBaseMgeSvr,dataDictionaryItemDao); } Test public void addExamination(){ when(examinationDao.insert(any())).thenReturn(1); Examination examination new Examination(); examination.setKeyId(UUID.randomUUID()); Assert.assertEquals(examinationBaseSvr.addExamination(,examination),examination); } Test public void addExcaminations(){ ExaminationList examinations new ExaminationList(); Examination examination new Examination(); examination.setKeyId(UUID.randomUUID()); examinations.add(examination); doAnswer(invocation - { ListExamination examinationList (ListExamination)invocation.getArguments()[0]; Assert.assertEquals(examinationList,examinations.getItems()); return 1; }).when(examinationDao).insertList(any()); examinationBaseSvr.addExaminations(,examinations); } Test public void modifyExamination(){ when(examinationDao.update(any())).thenReturn(1); Examination examination new Examination(); examination.setKeyId(UUID.randomUUID()); Assert.assertEquals(examinationBaseSvr.modifyExamination(,examination),examination); } Test public void modifyExaminations(){ ExaminationList examinations new ExaminationList(); Examination examination new Examination(); examination.setKeyId(UUID.randomUUID()); examinations.add(examination); doAnswer(invocation - { ListExamination examinationList (ListExamination)invocation.getArguments()[0]; Assert.assertEquals(examinationList,examinations.getItems()); return 1; }).when(examinationDao).updateList(examinations.getItems()); examinationBaseSvr.modifyExaminations(,examinations); } Test public void deleteExamination(){ Examination examination new Examination(); examination.setKeyId(UUID.randomUUID()); when(examinationDao.update(any())).thenReturn(1); when(examinationDao.getDetail(any())).thenReturn(examination); Assert.assertEquals(examinationBaseSvr.deleteExamination(,examination.getKeyId(),false),1); } Test public void deleteExaminations(){ ExaminationList examinations new ExaminationList(); Examination examination new Examination(); examination.setKeyId(UUID.randomUUID()); examinations.add(examination); doAnswer(invocation - { ListExamination examinationList (ListExamination)invocation.getArguments()[0]; Assert.assertEquals(examinationList,examinations.getItems()); return 1; }).when(examinationDao).updateList(any()); examinationBaseSvr.deleteExamination(,examinations,false); } }4.跑测试集测试类写完之后类名旁边有一个run的图标点击即可跑整个测试集。其中有普通的run以及带覆盖率报告的run选择带覆盖率的run之后会显示覆盖率相看类里面具体是哪些代码段被覆盖了可以在跑完测试集后进入具体的被测试类代码行旁边会有颜色条绿色表示被cover的内容

相关新闻

电力系统优化运行与编程:电网规划、负荷预测及潮流计算的Matlab代码模型复现

电力系统优化运行与编程:电网规划、负荷预测及潮流计算的Matlab代码模型复现

Matlab 电气工程 电力系统分析 编程 代码 模型复现。 1 研究内容:电力系统 优化运行 经济调度 电网规划 负荷预测 潮流计算 最优潮流 不确定性处理等领域。 2 研究对象:输电网 配电网 微电网 虚拟电厂电气冷热综合能源系统 交直流混联系统 多能源系统 双…

2026/7/4 15:28:18 阅读更多 →
嵌入式毕业设计新颖的开题报告集合

嵌入式毕业设计新颖的开题报告集合

【单片机毕业设计项目分享系列】 🔥 这里是DD学长,单片机毕业设计及享100例系列的第一篇,目的是分享高质量的毕设作品给大家。 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的单片机项目缺少创新和亮点…

2026/7/4 12:56:16 阅读更多 →
毕设程序javaJava停车场管理系统 基于SpringBoot的智慧停车服务平台设计与实现 城市智能车位管理与运营系统开发

毕设程序javaJava停车场管理系统 基于SpringBoot的智慧停车服务平台设计与实现 城市智能车位管理与运营系统开发

毕设程序javaJava停车场管理系统8d7ng601(配套有源码 程序 mysql数据库 论文) 本套源码可以在文本联xi,先看具体系统功能演示视频领取,可分享源码参考。随着城市化进程的加速推进和机动车保有量的持续攀升,停车资源供需矛盾日益尖…

2026/7/4 2:17:59 阅读更多 →

最新新闻

天龙八部GM工具:3分钟掌握游戏数据自由编辑的终极方法

天龙八部GM工具:3分钟掌握游戏数据自由编辑的终极方法

天龙八部GM工具:3分钟掌握游戏数据自由编辑的终极方法 【免费下载链接】TlbbGmTool 某网络游戏的单机版本GM工具 项目地址: https://gitcode.com/gh_mirrors/tl/TlbbGmTool 还在为游戏中重复刷怪升级而烦恼?想要快速体验天龙八部单机版的全部内容…

2026/7/4 21:03:51 阅读更多 →
Vault-Operator在生产环境中的最佳实践:来自实际部署的经验分享

Vault-Operator在生产环境中的最佳实践:来自实际部署的经验分享

Vault-Operator在生产环境中的最佳实践:来自实际部署的经验分享 【免费下载链接】vault-operator Run and manage Vault on Kubernetes simply and securely 项目地址: https://gitcode.com/gh_mirrors/va/vault-operator Vault-Operator是一款在Kubernetes环…

2026/7/4 21:03:51 阅读更多 →
智能绕过限制:永久免费使用Cursor AI编程助手的完整方案

智能绕过限制:永久免费使用Cursor AI编程助手的完整方案

智能绕过限制:永久免费使用Cursor AI编程助手的完整方案 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reached your t…

2026/7/4 21:01:50 阅读更多 →
毕设分享 深度学习yolo藻类细胞检测识别(科研辅助系统)(源码+论文)

毕设分享 深度学习yolo藻类细胞检测识别(科研辅助系统)(源码+论文)

👆👆 完整项目获取方式👆👆完整项目获取方式👆👆完整项目获取方式👆👆完整项目获取方式👆👆 文章目录 👆👆 完整项目获取方式&#x1…

2026/7/4 21:01:50 阅读更多 →
Blender高效工作流终极指南:从插件到渲染的全方位专业技巧

Blender高效工作流终极指南:从插件到渲染的全方位专业技巧

Blender高效工作流终极指南:从插件到渲染的全方位专业技巧 【免费下载链接】awesome-blender 🪐 A curated list of awesome Blender addons, tools, tutorials; and 3D resources for everyone. 项目地址: https://gitcode.com/GitHub_Trending/aw/aw…

2026/7/4 20:59:49 阅读更多 →
Windows系统优化与自动化部署:WinUtil工具箱完整指南

Windows系统优化与自动化部署:WinUtil工具箱完整指南

Windows系统优化与自动化部署:WinUtil工具箱完整指南 【免费下载链接】winutil Chris Titus Techs Windows Utility - Install Programs, Tweaks, Fixes, and Updates 项目地址: https://gitcode.com/GitHub_Trending/wi/winutil 面对Windows系统臃肿、软件安…

2026/7/4 20:57:48 阅读更多 →

日新闻

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 正式发布,这是一个关键的安全修复版本,修复了多个方面的问题,还对部分功能进行了优化。 安全修复亮点 此次发布在安全修复上表现突出。binprot 避免了项目引用计数溢出,mcmc 因安全问题提升了上游版本号&#xf…

2026/7/4 0:04:29 阅读更多 →
终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案 【免费下载链接】HMCL A Minecraft Launcher which is multi-functional, cross-platform and popular 项目地址: https://gitcode.com/gh_mirrors/hm/HMCL HMCL(Hello Minecraft! Lau…

2026/7/4 0:06:29 阅读更多 →
KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

1. KMX63与PIC18F66K40的硬件协同架构解析KMX63作为一款三轴加速度计和磁力计组合传感器,与PIC18F66K40微控制器的搭配堪称嵌入式HMI开发的黄金组合。这套硬件组合的核心优势在于KMX63提供的高精度运动感知能力与PIC18F66K40强大的信号处理能力形成了完美互补。KMX6…

2026/7/4 0:06:29 阅读更多 →

周新闻

月新闻