单元测试Mock中常见问题与解决方案

2024-06-03 12:12

本文主要是介绍单元测试Mock中常见问题与解决方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

很久不写博客了,经常搜索前辈和晚辈写的问题解决方案,得到很多帮助,也受益匪浅,所以也时常感到愧疚。那么接下来一段时间,我也分享一些技术点,问题方案吧。闻道有先后,术业有专攻。也希望我们都能保持一颗谦卑的心向身边或网络上的人学习,因为每个人都有自己的闪光点……

本篇单元测试暂时局限于mock、powermock,引用的jar包,大家自行百度吧。很简单。Demo样例,网上也多,后续我也可以给大家一些代码样例。

一、常见问题与解决方案

1、when().thenReturn()中常见问题

1.1. mock模拟的请求参数是对象,传入对象的每个元素值都对,但是报错

SysInfo sysInfo = new SysInfo();

sysInfo.setAct("abc");

when(systemInfoService.querySysParamsCount(sysInfo)).thenReturn(1);

问题:功能代码运行时生成的对象和mock传入的对象,对象内每个元素的值都一样,但是返回异常。

解决方案:请求对象对应的类SysInfo没有重写equals和hashCode方法。

传入的对象是map,会有这种问题吗?

不会。

1.2. 请求参数除了可以用any(),anyString,还可以用什么替代?

解决方案:还可以用any(类名.class)

1.3. 模拟while、for循环的参数时,如何跳出循环?

解决方案:thenReturn后再增加一个thenReturn,意思就是返回值有多种情况。第二次遍历时,就会变成下一个返回值。

例如:

when(systemInfoService.querySysParams(any()).thenReturn(sysInfoList ).thenReturn(sysInfoList2 );

1.4. 静态变量的mock——MockedStatic,多个类使用时,出现already regestered的问题

例如声明了一个MockedStatic

MockedStatic<DateUtil> dateUtilMockedStatic;

解决方案:

有可能是因为静态变量没关闭,那么就在调用的方法内执行到最后调用这个静态mock的close方法,或者在@After对应方法内,调用它的close方法。

还有一种更容易发生的错误,前面没加this

生成这个变量,关闭它,都要在前面加“this.”

也就是

MockedStatic<DateUtil> dateUtilMockedStatic;@Before
public void setUp() {openMocks(this);this.dateUtilMockedStatic = mockStatic(DateUtil.class);
}@After
public void destroy(){this.dateUtilMockedStatic.close();
}

why?应该是因为,我们声明的静态变量不加this,就是属于整个包或者整个项目,所以导致的重复注册问题。

1.5. 对于同一个方法调用,返回的类型不一致,如何mock?

对于这种情况,可以用when().thenReturn(map).thenReturn(intNum).thenReturn(str)...thenReturn(map)形式,返回功能代码逐次调用的同名方法不同返回值的对应返回值。

注意:这种返回mock,针对每一次功能内某个总方法的调用来都需要mock一次。

2. ReflectTestUtil作为反射的使用

3. MockStatic

4.

二、注意事项:

1、我们是写单元测试的,不是写功能代码的,功能业务代码,一般是不能因为写单元测试去改动的!!!这一点非常重要。

2、单元测试代码也要尽可能优化,尽量不要为了简单,把对一个公共方法的单元测试,分几个好几个方法去mock测试,这样产生了大量冗余代码,也会增加编译运行时间,降低项目性能与开发效率。

三、单元测试中Idea工具调优与使用技巧

1、如果是gradle作为jar包版本工具,要配置gradle,让它编译和运行都在idea上直接执行,而不是在gradle工具上执行。

2、多个单元测试代码写完,可以选择test的根目录、主目录,执行单元测试。这样可以发现多个单元测试文件同时执行时的问题,及时改正,快速提高单元测试覆盖率。

四、单元测试代码样例

package com.example.demo;import org.assertj.core.util.DateUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.MockedStatic;import static org.mockito.ArgumentMatchers.anyMap;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.openMocks;/*** @Author HenryLee* @Description TODO* @Date 2024/5/27 22:16* @Version 1.0*/
public class MyControllerTest {@InjectMocksprivate MyController myController;MockedStatic<DateUtil> dateUtilMockedStatic;@Beforepublic void setUp() {openMocks(this);this.dateUtilMockedStatic = mockStatic(DateUtil.class);}@Afterpublic void destroy(){this.dateUtilMockedStatic.close();}@Testpublic void testController() {when(myController.getMsg()).thenReturn(null);}}

这篇关于单元测试Mock中常见问题与解决方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

MySQL逻辑删除与唯一索引冲突解决方案

《MySQL逻辑删除与唯一索引冲突解决方案》本文探讨MySQL逻辑删除与唯一索引冲突问题,提出四种解决方案:复合索引+时间戳、修改唯一字段、历史表、业务层校验,推荐方案1和方案3,适用于不同场景,感兴... 目录问题背景问题复现解决方案解决方案1.复合唯一索引 + 时间戳删除字段解决方案2:删除后修改唯一字

Java中读取YAML文件配置信息常见问题及解决方法

《Java中读取YAML文件配置信息常见问题及解决方法》:本文主要介绍Java中读取YAML文件配置信息常见问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录1 使用Spring Boot的@ConfigurationProperties2. 使用@Valu

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

全面解析MySQL索引长度限制问题与解决方案

《全面解析MySQL索引长度限制问题与解决方案》MySQL对索引长度设限是为了保持高效的数据检索性能,这个限制不是MySQL的缺陷,而是数据库设计中的权衡结果,下面我们就来看看如何解决这一问题吧... 目录引言:为什么会有索引键长度问题?一、问题根源深度解析mysql索引长度限制原理实际场景示例二、五大解决

SpringSecurity显示用户账号已被锁定的原因及解决方案

《SpringSecurity显示用户账号已被锁定的原因及解决方案》SpringSecurity中用户账号被锁定问题源于UserDetails接口方法返回值错误,解决方案是修正isAccountNon... 目录SpringSecurity显示用户账号已被锁定的解决方案1.问题出现前的工作2.问题出现原因各

Nginx 配置跨域的实现及常见问题解决

《Nginx配置跨域的实现及常见问题解决》本文主要介绍了Nginx配置跨域的实现及常见问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来... 目录1. 跨域1.1 同源策略1.2 跨域资源共享(CORS)2. Nginx 配置跨域的场景2.1

javax.net.ssl.SSLHandshakeException:异常原因及解决方案

《javax.net.ssl.SSLHandshakeException:异常原因及解决方案》javax.net.ssl.SSLHandshakeException是一个SSL握手异常,通常在建立SS... 目录报错原因在程序中绕过服务器的安全验证注意点最后多说一句报错原因一般出现这种问题是因为目标服务器

C++高效内存池实现减少动态分配开销的解决方案

《C++高效内存池实现减少动态分配开销的解决方案》C++动态内存分配存在系统调用开销、碎片化和锁竞争等性能问题,内存池通过预分配、分块管理和缓存复用解决这些问题,下面就来了解一下... 目录一、C++内存分配的性能挑战二、内存池技术的核心原理三、主流内存池实现:TCMalloc与Jemalloc1. TCM

MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案(最新整理)

《MyBatisPlus中update_time字段自动填充失效的原因分析及解决方案(最新整理)》在使用MyBatisPlus时,通常我们会在数据库表中设置create_time和update... 目录前言一、问题现象二、原因分析三、总结:常见原因与解决方法对照表四、推荐写法前言在使用 MyBATis

Java死锁问题解决方案及示例详解

《Java死锁问题解决方案及示例详解》死锁是指两个或多个线程因争夺资源而相互等待,导致所有线程都无法继续执行的一种状态,本文给大家详细介绍了Java死锁问题解决方案详解及实践样例,需要的朋友可以参考下... 目录1、简述死锁的四个必要条件:2、死锁示例代码3、如何检测死锁?3.1 使用 jstack3.2