java单元测试:Mockito常用技巧

Mockito是Java中最流行的Mock框架之一,主要用于创建和配置模拟对象(Mock),以测试代码的行为。Mockito使得单元测试更加简单和可控,特别是在需要隔离外部依赖的情况下。

  1. Mockito简介

  1.1 什么是Mockito

  Mockito是一个开源的Mock框架,旨在为Java单元测试提供简单、可读的Mock对象。它可以模拟类的行为,使测试代码能够在不依赖真实对象的情况下运行。

  1.2 为什么使用Mockito

  ·隔离外部依赖:可以模拟外部系统(如数据库、网络服务等),使测试更加独立。

  · 提高测试覆盖率:即使没有实现具体逻辑,也可以编写测试,确保接口和交互逻辑正确。

  · 便于测试边界条件:可以轻松模拟异常情况和边界条件,确保代码在各种情况下的稳定性。

  2. 安装Mockito

  使用Maven来安装Mockito依赖,编辑pom.xml文件,添加Mockito依赖:

<dependency><groupId>org.mockito</groupId><artifactId>mockito-core</artifactId><version>4.0.0</version><scope>test</scope></dependency>

如果你使用JUnit 5,还需要添加Mockito的JUnit 5扩展:


<dependency><groupId>org.mockito</groupId><artifactId>mockito-junit-jupiter</artifactId><version>4.0.0</version><scope>test</scope></dependency>

3. Mockito的核心功能

  3.1 创建Mock对象

  使用Mockito.mock()方法可以创建一个Mock对象:


import static org.mockito.Mockito.*;import org.junit.jupiter.api.Test;import static org.junit.jupiter.api.Assertions.*;public class UserServiceTest {@Testvoid testAddUser() {UserRepository mockRepository = mock(UserRepository.class);UserService userService = new UserService(mockRepository);User user = new User("John", "Doe");when(mockRepository.save(user)).thenReturn(user);User result = userService.addUser(user);assertEquals("John", result.getFirstName());verify(mockRepository, times(1)).save(user);}}

 3.2 配置Mock对象行为

  使用when和thenReturn方法配置Mock对象的行为:


UserRepository mockRepository = mock(UserRepository.class);User user = new User("John", "Doe");when(mockRepository.save(user)).thenReturn(user);

你还可以配置方法抛出异常:

when(mockRepository.save(user)).thenThrow(new RuntimeException("Save failed"));

 3.3 验证方法调用

  使用verify方法验证Mock对象的方法是否被调用,以及调用次数:

verify(mockRepository, times(1)).save(user);

常见的验证方法包括:

  ·verify(mock).methodCall():验证方法被调用

  · verify(mock, times(n)).methodCall():验证方法被调用n次

  · verify(mock, never()).methodCall():验证方法从未被调用

  3.4 参数匹配

  Mockito提供了多种参数匹配器(Matchers)用于更灵活的验证和配置行为:


import static org.mockito.ArgumentMatchers.*;when(mockRepository.findById(anyInt())).thenReturn(Optional.of(user));verify(mockRepository).findById(eq(1));

常见的匹配器包括:

  ·any():匹配任何参数

  · anyInt():匹配任何整数参数

  · eq(value):匹配特定值

  · isNull():匹配null值

  · notNull():匹配非null值

  4. 使用注解简化Mock配置

  Mockito提供了注解(Annotations)来简化Mock对象的创建和配置:

  4.1 @Mock

  @Mock注解用于创建Mock对象:


import org.junit.jupiter.api.BeforeEach;import org.junit.jupiter.api.Test;import org.mockito.InjectMocks;import org.mockito.Mock;import org.mockito.MockitoAnnotations;import static org.mockito.Mockito.*;public class UserServiceTest {@Mockprivate UserRepository userRepository;@InjectMocksprivate UserService userService;@BeforeEachvoid setUp() {MockitoAnnotations.openMocks(this);}@Testvoid testAddUser() {User user = new User("John", "Doe");when(userRepository.save(user)).thenReturn(user);User result = userService.addUser(user);assertEquals("John", result.getFirstName());verify(userRepository, times(1)).save(user);}}

4.2 @InjectMocks

  @InjectMocks注解用于自动注入Mock对象到被测试对象中:

  1.  @InjectMocks

  2.   private UserService userService;

5. 高级功能

  5.1 Spy

  Spy用于部分模拟对象,即部分使用真实对象的方法,部分使用Mock对象的方法:


List<String> list = new ArrayList<>();List<String> spyList = spy(list);when(spyList.size()).thenReturn(100);spyList.add("one");spyList.add("two");assertEquals(100, spyList.size());assertEquals("one", spyList.get(0));assertEquals("two", spyList.get(1));

5.2 ArgumentCaptor

  ArgumentCaptor用于捕获方法调用时传递的参数:

import org.mockito.ArgumentCaptor;ArgumentCaptor<User> captor = ArgumentCaptor.forClass(User.class);verify(userRepository).save(captor.capture());User capturedUser = captor.getValue();assertEquals("John", capturedUser.getFirstName());

6. 实践中的Mockito

  6.1 模拟依赖

  在实际项目中,Mockito常用于模拟依赖对象,如数据库访问层、远程服务等,使测试更加独立和可控。

  6.2 与JUnit结合

  Mockito通常与JUnit结合使用,特别是JUnit 5,利用@ExtendWith(MockitoExtension.class)简化Mock对象的初始化。


import org.junit.jupiter.api.extension.ExtendWith;import org.mockito.junit.jupiter.MockitoExtension;@ExtendWith(MockitoExtension.class)public class UserServiceTest {// 测试代码}

7. 总结

  Mockito是一个强大的Mock框架,为Java开发者提供了丰富的功能来创建和配置Mock对象。通过使用Mockito,可以隔离外部依赖,提高测试的独立性和稳定性。掌握Mockito的核心功能和高级用法,可以帮助你编写高效、可靠的单元测试。

行动吧,在路上总比一直观望的要好,未来的你肯定会感 谢现在拼搏的自己!如果想学习提升找不到资料,没人答疑解惑时,请及时加入扣群:,里面有各种软件测试+开发资料和技术可以一起交流学习哦。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

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

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

相关文章

QGC二次开发入门教程(一):课程大纲

文章目录 前言一、课程大纲二、修改软件名称三、修改软件图标四、官方QGC中文版BUG修复五、汉化六、修改商标七、添加信号-槽八、添加QML和C交互九、MAVLINK的解析与发送十、换地图十一、添加自定义mavlink消息十二、在主工具栏添加一个自定义图标十三、解析自定义mavlink数据并…

SVN文件夹没有图标(绿钩子和红感叹号)

3分钟教会你解决SVN文件夹没有绿勾和红色感叹号的问题_svn文件被改动过不显示红色-CSDN博客https://blog.csdn.net/weixin_43382915/article/details/124251563 关于SVN状态图标不显示的解决办法(史上最全) - 简书 (jianshu.com)https://www.jianshu.com/p/92e8e1f345c0

华为OD机试D卷 --剩余银饰的重量--24年OD统一考试(Java JS Python C C++)

文章目录 题目描述输入描述输出描述用例题目解析java源码js源码python源码c源码c++源码题目描述 有 N 块二手市场收集的银饰,每块银饰的重量都是正整数,收集到的银饰会被熔化用于打造新的饰品。 每一回合,从中选出三块最重的银饰,然后一起熔掉。 假设银饰的重量分别为 x…

人工智能与机器学习原理精解【6】

文章目录 数值优化基础理论凹凸性定义在国外与国内存在不同国内定义国外定义总结示例与说明注意事项 国内凹凸性二阶定义的例子凹函数例子凸函数例子 凸函数&#xff08;convex function&#xff09;的开口方向凸函数的二阶导数凸函数的二阶定义单变量函数的二阶定义多变量函数…

微信小程序下载预览PDF并且分享出去

wx.downloadFile({url: url, //要预览的PDF的地址// filePath: ${wx.env.USER_DATA_PATH}/${docName}.pdf, // 添加后缀&#xff0c;可以分享出去success: function (res) { console.log(res);if (res.statusCode 200) { //成功const { filePa…

基于springboot+vue+uniapp的网上花店小程序

开发语言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#…

DNS主从服务架构(thirteen day)

回顾 编号主机名IP地址说明修改1web服务器192.168.1.11发布部署web服务发布了一个nginx web服务2DNS服务器192.168.1.22用于解析域名和IP地址 1、安装bind 2、配置一个conf&#xff0c;zones&#xff0c;zone 3、检查了3个文件 4、启动 3client主机192.168.1.33用于模拟客户机…

FreeSWITCH 1.10.10 简单图形化界面26-在网页上播放SIP设备视频

​ FreeSWITCH 1.10.10 简单图形化界面26-在网页上播放SIP设备视频 1、前言2、大概流程3、测试环境4、安装流媒体服务器5、设置流媒体服务器接口6、简单写个web接口7、测试一下1、web播放在线播放器1在线播放器2本地video控件 2、vlc播放vlc播放rtmpvlc播放rtsp 8、总结 1、前…

https改造-python https 改造

文章目录 前言https改造-python https 改造1.1. https 配置信任库2. 客户端带证书https发送,、服务端关闭主机、ip验证 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每…

git操作的一些备忘录

1.回退本地合并 git merge --abort 2.撤销上一次的提交 方法一&#xff1a;(已经提交到git线上仓库了&#xff0c;git reset操作&#xff0c;会把之前提交的都删除&#xff0c;感觉有点危险) 想要让Git回退历史&#xff0c;有以下步骤&#xff1a; 使用git log命令&#xff0c…

SpringSecurity--DelegatingFilterProxy工作流程

什么是 DelegatingFilterProxy&#xff1f; DelegatingFilterProxy 是 Spring 提供的一个特殊的过滤器&#xff0c;它起到了桥梁的作用&#xff0c;可以让你在 Spring 容器中管理 Servlet 容器中的过滤器。 为什么需要 DelegatingFilterProxy&#xff1f; 通常情况下&#x…

【项目日记(三)】梦幻笔耕-博客模块

❣博主主页: 33的博客❣ ▶️文章专栏分类:项目日记◀️ &#x1f69a;我的代码仓库: 33的代码仓库&#x1f69a; &#x1faf5;&#x1faf5;&#x1faf5;关注我带你了解更多项目内容 目录 1.前言2.获取博客列表3.获取博客详情4.新增博客5.更新博客6.删除博客7.拦截器9.统一处…

日常开发记录分享-SQL中的partition分区功能使用

文章目录 需求来源实现思路实施SQL 语句结构内部查询&#xff08;子查询&#xff09;外部查询 结果 partition的升级使用解释 验证一下看看分区 分区的一些操作1. 普通查询2. 分区表上的查询优化3. 插入数据4. 删除分区中的数据5. 分区维护操作添加新的分区删除分区重组分区 6.…

银河麒麟服务器V10 SP3 安装人大金仓V009R001C001B0030

原文链接&#xff1a;银河麒麟服务器V10 SP3 安装人大金仓V009R001C001B0030 Hello&#xff0c;大家好啊&#xff0c;今天给大家带来一篇关于在银河麒麟服务器V10 SP3上安装人大金仓V009R001C001B0030的文章。人大金仓是国内知名的数据库管理系统&#xff0c;它在高性能、高可靠…

AWS全服务历史年表:发布日期、GA和服务概述一览 (全)

我一直在尝试从各种角度撰写关于Amazon Web Services&#xff08;AWS&#xff09;的信息和魅力。由于我喜欢技术历史&#xff0c;这次我总结了AWS服务发布的历史年表。 虽然AWS官方也通过“Whats New”发布了官方公告&#xff0c;但我一直希望能有一篇文章将公告日期、GA日期&…

【C++】标准库:介绍string类

string 一.string类介绍二.string类的静态成员变量三.string类的常用接口1.构造函数&#xff08;constructor&#xff09;2.析构函数&#xff08;destructor&#xff09;3.运算符重载&#xff08;operator&#xff09;1.operator2.operator[]3.operator4.operator 4.string的四…

算法从零到精通 (一) ~ 快慢双指针

1. 前言 快慢双指针是一种常用的算法技巧&#xff0c;通常用于解决涉及链表或数组的问题。它的基本思想是使用两个指针&#xff0c;一个移动速度快&#xff08;快指针&#xff09;&#xff0c;一个移动速度慢&#xff08;慢指针&#xff09;&#xff0c;来解决特定的问题。这两…

计算机软考之计算机网络知识详解

目录 计算机网络概述计算机网络体系结构 OSI参考模型TCP/IP模型 物理层 传输介质信号传输 数据链路层 数据帧错误检测与纠正 网络层 IP协议路由协议 传输层 TCP协议UDP协议 应用层 常见应用层协议 网络安全 常见安全威胁安全措施 实战案例分析总结 计算机网络概述 计算机网络…

Docker搭建群晖

Docker搭建群晖 本博客介绍在docker下搭建群晖 1.编辑docker-compose.yml文件 version: "3" services:dsm:container_name: dsmimage: vdsm/virtual-dsm:latestenvironment:DISK_SIZE: "16G"cap_add:- NET_ADMIN ports:- 8080:50…

在未来有可能实现无药无手术可以治病吗?

在未来&#xff0c;随着科技的不断进步和人类对健康的追求&#xff0c;无药无手术治病的可能性是存在的。虽然目前的技术水平和医疗手段还无法完全实现这一目标&#xff0c;但是我们可以从多个方面推论出未来可能出现的无药无手术治病的情景。 首先&#xff0c;随着生物科技的发…