用好 mock 事半功倍

一、常用的mock工具

在Java开发中,Mock工具可用于单元测试和模拟对象的创建

1、Mockito:

        Mockito是Java中最受欢迎的Mocking框架之一。
        提供简单易用的API,可以方便地创建和配置模拟对象。
        支持验证模拟对象的行为和交互。
        提供了注解支持,用于简化测试代码的编写。
        文档丰富,社区活跃,广泛应用于Java项目中,SpringBootTest 默认使用的也是 Mockito
2、EasyMock:

        EasyMock是另一个常用的Java Mocking框架。
        提供了单的API来创建和配置模拟对象。
        支持验证模拟对象的行为和交互。
        使用了基于录制和回放的模拟对象创建方式。
        语法相对于Mockito来说稍微繁琐一些。
        文档相对较少,但社区比较活跃。
3、PowerMock:

        PowerMock是一个扩展了Mockito和EasyMock功能的工具。
        可以模拟静态方法、构造函数、私有方法等。
        PowerMock的使用相对复杂,需要在测试类上使用特定的注解。
        在处理一些特殊场景(如遗留代码)时非常有用。
        文档相对较少,但在特定情况下仍然是一个有价值的工具。

二、spring / 非 spring 场景测试验证

选取的mock工具为 mockito ,其中依赖版本为 mockito-core:3.3.3 

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

1、场景假设,我们的希望实现用户在线时长查询的方法,其中需要校验用户是否登陆(第三方接口)

@Service
public class LoginService {@Resourceprivate SSOService ssoService;/*** 调用单点登陆系统判断* @param userId* @return*/public boolean isLogin(String userId) {UserInfo userInfo = ssoService.getLoginInfo(userId);if (Objects.nonNull(userInfo)) {return true;}return false;}
}@Service
public class UserService {@Resourceprivate LoginService loginService;/*** 获取用户在线时常* @return*/public Integer getUserOnlineTimes(String userId){//判断是否登陆if(!loginService.isLogin(userId)){return 0;}return  (int)(Math.random() * 100) + 1;}
}

2、在没有SSO调用授权之前我们不好进行单元测试,这时就需要用的mock工具了

a、非 spring 方式使用mock进行测试验证,通过反射注入 mock 类

@Slf4j
@RunWith(MockitoJUnitRunner.class)
public class UserServiceTest {@Mockprivate LoginService loginServiceMock;@Testpublic void getUserOnlineTimes() throws NoSuchFieldException, IllegalAccessException {// 设置 mock 场景Mockito.when(loginServiceMock.isLogin("zhangsan")).thenReturn(false);Mockito.when(loginServiceMock.isLogin("lisi")).thenReturn(true);// 反射赋值属性 或 在 userService 作为成员变量,使用 @InjectMocks 注入UserService userService = new UserService();Field loginService = userService.getClass().getDeclaredField("loginService");loginService.setAccessible(true);loginService.set(userService, loginServiceMock);//验证Integer onlineTimes = userService.getUserOnlineTimes("zhangsan");Assert.assertEquals(Integer.valueOf(0), onlineTimes);onlineTimes = userService.getUserOnlineTimes("lisi");Assert.assertTrue(onlineTimes > 0);}
}

b、非 spring 方式使用mock进行测试验证,通过 mockito 注解 @InjectMocks 注入

@Slf4j
@RunWith(MockitoJUnitRunner.class)
public class UserServiceTest2 {@Mockprivate LoginService loginServiceMock;@InjectMocksprivate UserService userService;@Testpublic void getUserOnlineTimes() {// 设置 mock 场景Mockito.when(loginServiceMock.isLogin("zhangsan")).thenReturn(false);Mockito.when(loginServiceMock.isLogin("lisi")).thenReturn(true);//验证Integer onlineTimes = userService.getUserOnlineTimes("zhangsan");Assert.assertEquals(Integer.valueOf(0), onlineTimes);onlineTimes = userService.getUserOnlineTimes("lisi");Assert.assertTrue(onlineTimes > 0);// 验证mock方法被执行的次数Mockito.verify(loginServiceMock, Mockito.times(1)).isLogin("zhangsan");}
}

c、spring 容器中使用mock进行测试验证

@Slf4j
@SpringBootTest
@RunWith(SpringRunner.class)
public class UserServiceTestInSpring {@MockBeanprivate LoginService loginServiceMock;@Resourceprivate UserService userService;@Beforepublic void init(){// 启用mockMockitoAnnotations.initMocks(this);}@Testpublic void getUserOnlineTimes() {// 设置 mock 场景Mockito.when(loginServiceMock.isLogin("zhangsan")).thenReturn(false);Mockito.when(loginServiceMock.isLogin("lisi")).thenReturn(true);//验证Integer onlineTimes = userService.getUserOnlineTimes("zhangsan");Assert.assertEquals(Integer.valueOf(0), onlineTimes);onlineTimes = userService.getUserOnlineTimes("lisi");Assert.assertTrue(onlineTimes > 0);}
}
三、mockito 使用总结

Mockito提供了强大的验证功能,支持验证模拟对象的方法调用次数、参数和顺序,以确保代码的预期行为,另外注解的支持可以轻松地创建和注入模拟对象,让测试代码更加简化,但是Mockito本身无法直接模拟静态方法和私有方法。对于这些场景,可以使用 PowerMock 或者使用java代码直接构造生成

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

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

相关文章

普冉(PUYA)单片机开发笔记(4): 配置通用定时器

概述 在前几篇开发笔记中&#xff0c;从 PY32F003 的一个厂家标准例程开始&#xff0c;实现了中断式无阻塞串口收发、对开发板 LED3 的亮/灭控制&#xff0c;时钟系统的初始化和时钟选择。在此基础上&#xff0c;今天做一下定时器的应用实验。事先考虑以下几个问题&#xff1a…

【C语言】函数调用及创建,并将数组传参到函数

&#x1f3a5; 岁月失语唯石能言的个人主页 &#x1f525;个人栏专&#xff1a;秒懂C语言 ⭐若在许我少年时&#xff0c;一两黄金一两风 目录 前言 一、函数的概念 二、库函数 2.1 标准库和头文件 2.2库函数的使用方法 2.2.1功能 2.2.2库函数的头文件 2…

一些程序源码及教程的网站合集~

很多时候我们需要一个快速上手的code demo及教程&#xff0c;除了最常用的【github】&#xff0c;一些中文网站可能会帮助我们更好上手~ 这里提供几个中文网站参考&#xff1a; 【51CTO】&#xff1a; Python 动态手势识别系统hmm 手势识别opencv_mob64ca140d96d9的技术博客…

19、WEB攻防——.NET项目DLL反编译未授权访问配置调试报错

文章目录 一、.NET项目——DLL文件反编译指向—代码特性二、.NET项目——Web.config错误调试—信息泄露三、.NET项目——身份验证未授权访问—安全漏洞 web搭配&#xff1a; windowsiisaspaccesswindowsiisaspxsqlserver 一、.NET项目——DLL文件反编译指向—代码特性 bin目…

【Linux】探索Linux进程优先级 | 环境变量 |本地变量 | 内建命令

最近&#xff0c;我发现了一个超级强大的人工智能学习网站。它以通俗易懂的方式呈现复杂的概念&#xff0c;而且内容风趣幽默。我觉得它对大家可能会有所帮助&#xff0c;所以我在此分享。点击这里跳转到网站。 目录 一、进程优先级1.1优先级VS权限1.2为什么要有进程优先级&am…

《YOLOv8改进系列》专栏目录介绍

YOLOv8改进系列 &#x1f680; 专栏目录介绍 本专栏内容是紧跟最新、最前沿的改进方法&#xff0c;不仅适用检测任务&#xff0c;分类任务&#xff0c;分割任务&#xff0c;关键点任务同样适用。文章适用于多种场景&#xff0c;包括但不限于小目标、工业缺陷、轻量化等领域。 …

1.3 什么是接口?什么是接口测试?

上一小节我们认识了C/S和B/S架构,那在B/S架构中,我们测试最常接触的,就是接口。本课程的重点是接口自动化测试,那同学们真的了解什么是接口吗?首先,我们从通俗的角度来看什么是接口。在计算机中,接口是计算机系统中两个独立的部件进行信息交换的共享边界。这种交换可以发…

YOLOv8-pose关键点检测:模型轻量化创新 | 轻量化自研设计双卷积,修改backbone和neck,完成涨点且计算量和参数量显著下降

💡💡💡本文解决什么问题:双卷积由组卷积和异构卷积组成,执行 33 和 11 卷积运算代替其他卷积核仅执行 11 卷积,加入YOLOv8 backbone和ncek DualConv | GFLOPs从9.6降低至9.1,参数量6842kb降低至6393 ,mAP50从0.921提升至0.931,mAP50-95从0.697提升至0.726 Yolo…

防火墙访问控制、安全审计、网络设备防护检查表

1、访问控制类检查 2、安全审计类检查 3、网络设备防护类检查 原件&#xff1a; 防火墙标准检查表 分类 测评项 预期结果 访问控制 应在网络边界部署访问控制设备&#xff0c;启用访问控制功能 启用了访问控制规则 应能根据会话状态信息为数据流提供明确的允许/拒绝访…

HarmonyOS—实现UserDataAbility

UserDataAbility接收其他应用发送的请求&#xff0c;提供外部程序访问的入口&#xff0c;从而实现应用间的数据访问。Data提供了文件存储和数据库存储两组接口供用户使用。 文件存储 开发者需要在Data中重写FileDescriptoropenFile(Uriuri,Stringmode)方法来操作文件&#xf…

socket是如何进行通信的

Socket通信的原理大致分为以下几个步骤&#xff1a; 服务器端建立Socket&#xff0c;开始侦听整个网络中的连接请求。当检测到来自客户端的连接请求时&#xff0c;向客户端发送收到连接请求的信息&#xff0c;并建立与客户端之间的连接。当完成通信后&#xff0c;服务器关闭与…

bash命令: logrotate的使用

1. 概述 Linux服务器上运行的程序都会通过日志来告知外部自己的运行过程、结果以及遇到的问题&#xff0c;随着日志的不断累计&#xff0c;它会变的越来越大&#xff0c;所以常见的方案是根据时间或者日志文件的大小&#xff0c;对日志文件进行轮转&#xff0c;比如Java程序里…

简单使用selenium抓取微博热搜话题存储进Excel表格中

#test.pyimport requests from selenium import webdriver import time from write import write#首先打开浏览器 drive webdriver.Chrome()#设置隐式等待&#xff1a;等待元素找到&#xff0c;如果找到元素则马上继续执行语句&#xff0c;如果找不到元素&#xff0c;会在设定…

【PWN】学习笔记(三)【返回导向编程】(下)

目录 课程回顾动态链接过程 课程 课程链接&#xff1a;https://www.bilibili.com/video/BV1854y1y7Ro/?vd_source7b06bd7a9dd90c45c5c9c44d12e7b4e6 课程附件&#xff1a; https://pan.baidu.com/s/1vRCd4bMkqnqqY1nT2uhSYw 提取码: 5rx6 回顾 管道符 | 把前一个指令的输出作…

动物疾控中心污水处理设备工艺特点

诸城市鑫淼环保小编带大家了解一下动物疾控中心污水处理设备工艺特点 1、采用中和沉淀、复合式消毒、UV紫外线光波灭菌、臭氧氧化、多介质过滤等技术处理废水中的各类污染物; 2、利用pH计和进口计量泵控制投药量,并设有液位控制、水位报警等装置; 3、操作方便,运行稳定,使用寿命…

Jira 中如何修改时间为绝对时间

问题描述 在使用Jira的时候&#xff0c;有一些时间显示的是相对时间&#xff0c;如&#xff1a;2天前&#xff0c;3个小时前等&#xff0c;有些用户不习惯这样的显示方式&#xff0c;希望使用绝对的时间格式&#xff0c;如&#xff1a;2022年2月22日 22:22 应该怎样修改 解…

用python打印出菱形图案

你可以使用Python编写一个简单的函数来打印菱形图案。下面是一个例子&#xff0c;这个函数接受一个参数n&#xff0c;表示菱形的高度&#xff0c;然后打印出一个菱形图案&#xff1a; def print_diamond(n): # 上半部分 for i in range(n): print(" " …

python 多进程

python 多进程 多进程和多线程什么是进程什么是线程多进程和多线程的区别与联系优缺点多线程的优点多线程的缺点多进程的优点多进程的缺点 选择多线程还是多进程&#xff1f; 多进程使用multiprocessing.Process创建多进程通过multiprocessing.Process模块创建继承Process类来创…

springboot098基于web的网上摄影工作室的开发与实现

springboot098基于web的网上摄影工作室的开发与实现 源码获取&#xff1a; https://docs.qq.com/doc/DUXdsVlhIdVlsemdX

Java Applet 基础

标题&#xff1a;Java Applet 基础 介绍&#xff1a; Java Applet是Java语言提供的一种用于在网页中嵌入小型程序的技术。通过使用Java Applet&#xff0c;开发者可以在网页中添加交互性和动态性。本文将介绍Java Applet的基本概念和使用方法&#xff0c;并提供相应的示例代码…