IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> Mockito超全用例文档 -> 正文阅读

[开发测试]Mockito超全用例文档

一.mockito要注意的点

1. mock的对象直接调用其方法会返回null

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zGsN4OKA-1631189258292)(Untitled.assets/clipboard.png)]

2.执行真实的被测试方法

①thenCallRealMethod + 实现类:

解析:

mock接口不能和callRealMethod一起用,因为接口没有实现!(即使用spy重新封装也不行!)会报错哦~

但是,如果callRealMethod的方法里面用到了其他外部接口的方法,并且最后结果依赖于这些接口的返回值,则最后执行真实方法得到的接口会偏离真实结果,除非你其他方法也一起callRealMethod。

@Mock
private static LogisticsExpenseCostServiceImpl logisticsExpenseCostService;// 正确:mock被测试类实现类
//@Mock
//private static LogisticsExpenseCostServiceImpl logisticsExpenseCostService;// 错误:mock接口且想callRealMethod,

@org.junit.Test
public void test() throws ParseException {
    ... ...
when(logisticsExpenseCostService.findExpenseAndDetail(null, dataReadingEntity)).thenCallRealMethod();
List<ExpenseCostQueryItem> expenseAndDetail = logisticsExpenseCostService.findExpenseAndDetail(null, dataReadingEntity);
    ... ...
} 

②injectMock

解析:

@Mock: 创建一个Mock.

@InjectMocks: 创建一个实例,简单的说是这个Mock可以调用真实代码的方法,其余用@Mock(或@Spy)注解创建的mock将被注入到用该实例中。如果只实例化对象不加injectmock会,则被测试接口用到的其他依赖对象为空,无法注入报空指针。

但是,在doReturn().when(A)中,injectMcok的对象不能放入A的位置,因为A的位置只能是mock/spy对象,不过可以放在when(B).thenReturn()的B的位置,所以injectMock可以再用spy代理一起使用就可以用doReturn了

// 与mock不同,它需要new LogisticsExpenseCostServiceImpl()实例化
@InjectMocks
private static LogisticsExpenseCostService logisticsExpenseCostService = new LogisticsExpenseCostServiceImpl();
@org.junit.Test
public void test() throws ParseException {
    ...
    LogisticsExpenseCostService spy = spy(logisticsExpenseCostService);// spy代理
    doReturn(mockExpenseCostQueryItems).when(spy).constructExpenseCostList(null,dataReadingEntity);// 这里when(spy),不能when(logisticsExpenseCostService)~
    doReturn(mockExpenseCostDetailMap).when(spy).constructExpenseCostDetailMap(null,dataReadingEntity);
    List<ExpenseCostQueryItem> expenseAndDetail = spy.findExpenseAndDetail(null, dataReadingEntity);
    System.out.println(JSON.serialize(expenseAndDetail));
    ...
} 

3.verify测试是否被调用

在这里插入图片描述

4.激活mock功能的几种方式

在这里插入图片描述

二.mock对象的方式

1.spy

spy可以模拟部分实际代码,部分mock代码

被spy后,调用被打桩的方法会返回thenReturn/doReturn的值,调用没被打桩方法则是真实调用返回的值

使用方式:spy(XXX)或者@Spy注解

注意:被spy的对象需要已实例化(= new XXX, @Autowire…)

在这里插入图片描述

在这里插入图片描述

2.深度mock

优化需要把调用链所有涉及对象都mock的麻烦

使用方式:@Mock(answer=Answre.RETURNS_DEEP_STUBS)

如果不加此注解,那lession03Service.get()得到的对象也是需要mock才能用,否则空指针
在这里插入图片描述

三.stup打桩

1.doReturn.when:不会走函数方法

为了屏蔽复杂的第三方接口需要mock大量对象,使用doReturn直接屏蔽,注意参数匹配器,要是传参不匹配还是会走的

2.when.thenReturn:调用真实的方法

如果你不想调用真实的方法而是想要mock的话,就不要使用这个方法。

3.其他

thenReturn:模拟调用后返回值.

thenReturn多个参数:代表第x次返回参数位置x的值

thenThrow:模拟调用后抛异常

doNothing.when:模拟调用后不做任何事情

doThrow:模拟调用后抛异常

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7T2JpArJ-1631189258299)(Untitled.assets/clipboard-1631116202025.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qjyEssCe-1631189258300)(Untitled.assets/clipboard-1631116217446.png)]
在这里插入图片描述

thenAnswer:动态模拟返回参数值的十倍

在这里插入图片描述

四、Mockito argument Matchers 参数匹配器

1.anyXX

anyXXX的方法使用,可以减少很多打桩条件

在这里插入图片描述

2.isA和any

isA代表传入参数只要是A或A的实现子类都符合这个条件,可以返回桩

any只要符合function声明的参数,都可以通过

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NnI3Pzgs-1631189258301)(Untitled.assets/clipboard-1631116349521.png)]
在这里插入图片描述

五.常见错误

1.使用any常见错误,部分传入真实对象,部分传入any

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8jteTB6Q-1631189258302)(Untitled.assets/clipboard-1631116437691.png)]

那怎么办呢?使用eq实现具体值传参
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NU6q2F3h-1631189258303)(Untitled.assets/clipboard-1631116447551.png)]

2.verify的时候,调用的和校验的传参看似一样,其实不同对象导致校验报错

在这里插入图片描述

可以把对象抽出来,再放参数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oDVhwkHu-1631189258304)(Untitled.assets/clipboard-1631116466549.png)]

3.打桩顺序问题,-1放最后时,会覆盖前面两个打桩,因为anyString包括了eq(xxx)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WeUflYsd-1631189258304)(Untitled.assets/clipboard-1631116478394.png)]

如果这样写,后面两行只会覆盖部分的anyString,当为alex返回100,wang返回200,其他返回-1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-57dmwSiB-1631189258304)(Untitled.assets/clipboard-1631116490112.png)]

4.anyXX是不包括null的

比如有个参数类型是List,这时你when.thenReturn时传入anyList,而你最后调用时传入null,这时候是不符合when的打桩的

如果想包含null,可以使用any()

5.mock复杂的数据实体时,如果是多层数据结构,最里层的数据结构需要手动转类型

Map<String, List<ExpenseCostDetailQueryItem>> mockExpenseCostDetailMap = SnakeCaseJsonUtils.readObject("classpath:testData/expenseCostDetailMapJsonData",Map.class);
// 比如这里mock的数据返回是Map里面有个List,List里面是Model,当我们没有手动转类型,我们会得到JSONObeject的对象

// 手动转类型
for (Map.Entry<String, List<ExpenseCostDetailQueryItem>> stringListEntry : mockExpenseCostDetailMap.entrySet()) {
    List<ExpenseCostDetailQueryItem> value = stringListEntry.getValue();
    stringListEntry.setValue(JSONObject.parseArray(JSON.serialize(value),ExpenseCostDetailQueryItem.class));
}

6.doReturn肯定会跳过mock的方法,如果没有那就是你参数不匹配~

这里的参数是any任意值和dataReadingEntity实体,当你实际调用的dataReadingEntity和匹配器里的不同,那就不会跳过~

doReturn(mockExpenseCostQueryItems).when(spy).constructExpenseCostList(any(),eq(dataReadingEntity));

六.好的mockito习惯

1.善用@after

对不同方法里对同一个全局对象进行打桩,会互相影响,这时候加@after去reset可以避免影响

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EtVqWKwI-1631189258305)(Untitled.assets/clipboard-1631116544930.png)]

2.优雅的断言–陈述性断言

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GSHOG8gX-1631189258305)(Untitled.assets/clipboard-1631116552710.png)]

3.断言提示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1PLznEwr-1631189258306)(Untitled.assets/clipboard-1631116591809.png)]

4.手动实现断言条件

https://www.bilibili.com/video/BV1jJ411A7Sv?p=10

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-09-12 20:45:08  更:2021-09-12 20:45:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/21 5:18:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码