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,打桩

相关推荐
空中海几秒前
Docker入门到精通
java·docker·eureka
itzixiao12 分钟前
L1-067 洛希极限(10分)[java][python]
java·开发语言·算法
java1234_小锋20 分钟前
Spring AI 2.0 开发Java Agent智能体 - Spring AI项目调用本地Ollama模型
java·人工智能·spring·spring ai2.0
二哈赛车手20 分钟前
新人笔记---多策略搭建策略执行链实现RAG检索后过滤
java·笔记·spring·设计模式·ai·策略模式
PESS ABIN21 分钟前
JavaWeb项目打包、部署至Tomcat并启动的全程指南(图文详解)
java·tomcat
AI进化营-智能译站27 分钟前
ROS2 C++开发系列15-模板实现通用算法|宏定义ROS2调试开关|一次编码适配多平台
java·c++·算法·ai
刀法如飞30 分钟前
Java数组去重的20种实现方式——指导AI解决不同问题的思路
java·算法·面试
薪火铺子39 分钟前
SpringMVC请求处理流程源码解析(第1篇):请求入口与处理器映射
java·后端·spring
ch.ju39 分钟前
Java程序设计(第3版)第二章——参数(实参 形参)
java
椰猫子40 分钟前
SpringMVC(SpringMVC简介、请求与响应(请求映射路径、请求参数、日期类型参数传递、响应json数据))
java·前端·数据库