Junit4下Mockito包的使用

Spring环境下的单元测试--Junit4下Mockito包的使用

1.Mockito包是做什么的?

Mockito 是一个强大的 Java 单元测试框架,用于创建和管理 Mock 对象,帮助开发者在测试中模拟复杂的依赖关系。它通过简洁的 API 和强大的功能,使单元测试更加高效和易于维护。

​ 其实也就是帮助我创建一些对象,并且赋值上默认值,当然,这是针对方法也可以直接返回一个特定的想要的值,让我们除去复杂的数据而直接检验方法的逻辑。

2.怎么用?

<1>.注解使用

​ 先看Mokcito中的一些注解(以Junit4举例)

注解 作用 注意事项
@RunWith(SpringRunner.class) Spring进入测试生命周期的标识
@Mock 模拟一个对象,全部属性赋上默认值,里边的值都是虚拟的 mock的对象不可以再手动set其对应的属性,不会生效
@Spy 模拟一个真实对象,修改特定方法或属性,未修改的保留原有真实对象
@InjectMocks 将Mock的对象注入使用注解的对象中 一般来说你测试哪个类,就用在哪个类上

​ 这几个注解已经足够满足大部分的单元测试,当然还有一个静态方法的模拟。

​ 由于静态方法是类,并不为对象,对此@Mock和@Spy注解无能为力,那那么就该另一个注解登场,或者是不使用注解。

​ 先看注解:@MockStatic,之后还需要写一个MockStatic<你的对象>

java 复制代码
@MockStatic(你的对象.class)
private MockStatic<你的对象> 别名;

​ 不过建议放在ry-with-resources中,可以在使用完静态方法后自动关闭,防止脏数据影响到其他测试。

java 复制代码
 try (MockedStatic<你的对象> mocked = mockStatic(你的对象.class)) {
     //写具体的调用
 }

​ 讲完注解的,说说不用注解的

java 复制代码
//先创建对象
private MockedStatic<你的对象> 别名;
//在测试中的加上@before注解的方法中首先进行加载
别名 = Mockito.mockStatic(你的对象.class);
别名.when( () -> 你的对象.静态方法(参数)).thenReturn(具体值);
//这个时候还需要进行关闭,防止数据污染,在@after注解使用的方法中关闭
this.别名.close();
<2>.方法的调用

​ 一般来说都是用when进行包裹,这是Mockito中的一个静态方法

复制代码
框架大概为:
when(别名.方法(可填各种参数匹配的规则类型)).返回一个特定类型
1>. 返回特定值
java 复制代码
//下边解释为:当调用metaModelDao.findBySelectedIds()这个方法的时候,匹配的参数如果为任意的一个Sting数组的类,即返回一个自定义的result对象
when(metaModelDao.findBySelectedIds(any((String[].class)))).thenReturn(result);

//参数匹配还有哪些
when(metaModelDao.findBySelectedIds(eq("一个值或者是想要的对象等,一般用来比对值")))
    .thenReturn(result);

​ 参数匹配器大家可自行查阅,这里不做赘述,有了框架根据需求套就可以。

2>.动态返回值

​ 被测试的方法中对象不可能总是去手动打桩或者去mock,有的对象是会在方法中动态更新的。

​ 举一个例子来说:

​ 我现在需要修改一条数据,等到修改完毕之后 ,我需要从数据库中检查一下我的数据是否更新,那么此时我就需要再次调用一个dao层中的方法来获取,但在测试的时候完全没有必要这样,因为我们做单元测试一般来说会去做service层的测试,dao对象很明显就是mock出来的,那么它的方法也基本都是用when()来mock出来的,所以当其再查询一次的话,我就可以直接给他返回一个被测试方法中的对象,代码如下:

​ 原方法如下

java 复制代码
public void updateUser(User user,PromptMessage promptmessage){
    //检查判空等操作先不管
    User user = userDao.findOne(user);
    user.setAge(18);
    //类似于这种,具体逻辑先不管,此时的这个方法就没有必要再去mock了,直接把这个user返回就行了
    User user = userDao.update(user);
    ......
}

//测试方法
//解释:返回传入方法的第一个参数,第二个可以改变下标
when(userDao.update(any(User.class))).thenAnswer(ino -> ino.getArgument(0));
3>. 检验

​ 这是测试的关键一步,决定是否测试通过的一步。

​ Assert断言是经常被用到的。

java 复制代码
assertEquals(预期值,实际值);
//测试某个方法被调用了多少次,Times(1)可以省略,省略即默认为测试调用1次
verify(mock的类,Times(1)).方法(参数);

掌握这些基本可以解决90%的问题,剩下的问题就是不停的mock,mock,mock,打桩

相关推荐
qq_297574673 分钟前
【实战】POI 实现 Excel 多级表头导出(含合并单元格完整方案)
java·spring boot·后端·excel
星辰_mya6 分钟前
Elasticsearch线上问题之慢查询
java·开发语言·jvm
南极星10058 分钟前
我的创作纪念日--128天
java·python·opencv·职场和发展
郝学胜-神的一滴15 分钟前
超越Spring的Summer(一): PackageScanner 类实现原理详解
java·服务器·开发语言·后端·spring·软件构建
摇滚侠15 分钟前
Java,举例说明,函数式接口,函数式接口实现类,通过匿名内部类实现函数式接口,通过 Lambda 表达式实现函数式接口,演变的过程
java·开发语言·python
打工的小王19 分钟前
java并发编程(七)ReentrantReadWriteLock
java·开发语言
lang2015092819 分钟前
Java并发革命:JSR-133深度解析
java·开发语言
abluckyboy21 分钟前
基于 Java Socket 实现多人聊天室系统(附完整源码)
java·开发语言
Re.不晚25 分钟前
JAVA进阶之路——数据结构之线性表(顺序表、链表)
java·数据结构·链表
毅炼25 分钟前
Java 基础常见问题总结(3)
java·开发语言