文章目录

  • 一.mockito要注意的点
    • 1. mock的对象直接调用其方法会返回null
    • 2.执行真实的被测试方法
    • 3.verify测试是否被调用
    • 4.激活mock功能的几种方式
  • 二.mock对象的方式
    • 1.spy
    • 2.深度mock
  • 三.stup打桩
    • 1.doReturn.when:不会走函数方法
    • 2.when.thenReturn:调用真实的方法
    • 3.其他
  • 四、Mockito argument Matchers 参数匹配器
    • 1.anyXX
    • 2.isA和any
  • 五.常见错误
    • 1.使用any常见错误,部分传入真实对象,部分传入any
    • 2.verify的时候,调用的和校验的传参看似一样,其实不同对象导致校验报错
    • 3.打桩顺序问题,-1放最后时,会覆盖前面两个打桩,因为anyString包括了eq(xxx)
    • 4.anyXX是不包括null的
    • 5.mock复杂的数据实体时,如果是多层数据结构,最里层的数据结构需要手动转类型
    • 6.doReturn肯定会跳过mock的方法,如果没有那就是你参数不匹配~
  • 六.好的mockito习惯
    • 1.善用@after
    • 2.优雅的断言--陈述性断言
    • 3.断言提示
    • 4.手动实现断言条件

一.mockito要注意的点

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

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:模拟调用后抛异常



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

四、Mockito argument Matchers 参数匹配器

1.anyXX

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

2.isA和any

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

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


五.常见错误

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

那怎么办呢?使用eq实现具体值传参

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

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

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

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

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可以避免影响

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

3.断言提示

4.手动实现断言条件

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

Mockito超全用例文档相关推荐

  1. Android源码的Binder权限是如何控制,附超全教程文档

    从初中级到高级,移动端程序员的进阶宝典 想要成为一名优秀的Android开发,你需要一份完备的 知识体系,在这里,让我们一起成长为自己所想的那样. 下面我们就以 Android 开发为例,从硬技能和软 ...

  2. java开发五年多少钱,附超全教程文档

    一.分布式架构学习路线图 据统计,人的阅读时间在20分钟以内是能够达到全身心投入的,顾文章单张篇幅以后会尽量缩短,但更新会尽量相应频繁一些. 二.计算机软件发展历史 首先我们了解下计算机软件的发展历史 ...

  3. 正式加入阿里巴巴!跟Android初学者分享几点经验,附超全教程文档

    O(∩_∩)O~今天又给大家带来了21道Android高级面试题,搞懂了这些相信你去面试的时候一定可以镇住面试官 为此我把这些知识整理成了一个983页PDF,从基础到进阶.含有BATJ.字节跳动面试专 ...

  4. Android开发唯一的出路:进阶学习,附超全教程文档

    为啥经常听到程序员朋友说自己太辛苦了.太累了,其实原因很简单:干活苦.竞争大.技术致富难. 干活苦: 有新闻说晚上十点某领导在微信群要求下属在十分钟内回复,一员工因休息早而没及时回复被裁了. 对于程序 ...

  5. 移动开发技术总结!字节大神强推千页PDF学习笔记,附超全教程文档

    Android开发的现状 目前,移动开发已经处于饱和的阶段,Android开发也不如当年盛况,已经不再像前几年前那么火爆.正如一种编程语言如果经历过盛极一时,那么必然有这样的一条曲线,像我们学的正弦曲 ...

  6. 和快手大牛的技术面谈,附超全教程文档

    个人背景 如标题所示,我的个人背景非常简单,Java开发经验1年半,学历普通,2本本科毕业,毕业后出来就一直在Crud,在公司每天重复的工作对我的技术提升并没有什么帮助,但小镇出来的我也深知自我努力的 ...

  7. 最强整理!字节跳动历年Android中高级面试题全收录!附超全教程文档

    开头 让我们一起来看看,字节跳动的第三面,面试官都问了什么?(第一二面的题目及答案已整理,需要的可以在文末领取) 从七月中旬开始,我前前后后差不多一共投递了八十份简历,到目前为止,我参加面试的面试有十 ...

  8. Android开发技巧!Android开发大佬的百度,美团,快手等大厂Offer收割之旅,附超全教程文档

    想要成为一名优秀的Android开发,你需要一份完备的知识体系,在这里,让我们一起成长为自己所想的那样. 本文参考了目前大部分 Android 应用启动优化的方案,将大家的方案做一个汇总,如果你有这方 ...

  9. 涨知识!阿里P7级别面试经验总结,附超全教程文档

    咸鱼翻身不断上演 2018年5月份,北京,在所谓的互联网寒冬里,一个普通二本的学生,在小公司工作一年后,跳槽拿到了百度的offer,月薪从9k变为17k,涨薪幅度接近100%. 2018年底,上海,一 ...

最新文章

  1. Mysql游标循环遍历_MySQL数据库中,使用游标循环遍历
  2. php新增数组函数,php操作数组函数
  3. Dataset之Boston:Boston波士顿房价数据集的简介、下载、使用方法之详细攻略
  4. (转帖)对抽象编程:接口和抽象类
  5. 你的输入法都暴露了些啥?
  6. rabbitmq怎么停止_Windows环境下RabbitMQ的启动和停止命令
  7. c语言字符串字节数函数,C语言字符,字符串,字节操作常用函数
  8. Spring Boot 实现微信小程序订阅模板消息
  9. 红外图像和热成像图像
  10. Win 10 专业版重新激活详细操作步骤
  11. 如何将图片批量压缩大小?怎样一次性压缩多张图片?
  12. 在追寻梦想的路上,我们都一样
  13. RESTful及其特点
  14. Nacos入门之服务注册中心以及命名空间分组和DataID三者关系
  15. 案例:仿小米logo渐变效果练习
  16. 富士施乐FujiXeroxDocuCentre-V2060扫描到PC
  17. 最窄770PX最宽1024PX经典布局[DIV+CSS]
  18. kettle使用--1.mysql多表关联导入mongoDB
  19. JAVA——反转的两种方法
  20. 二进制八进制相互转换

热门文章

  1. 万物互联时代的操作系统报告 附下载地址
  2. Windows下安装Redis教程
  3. 成都天瑞地安:零基础学Java最快捷的7个计划
  4. 【k8s】kubectl label命令(对node添加、删除label)
  5. 东野圭吾梦幻花读后感_让梦幻花绽放在心灵深处——读东野圭吾《梦幻花》有感...
  6. 考研C语言复习02(小甲鱼版本)
  7. Java程序优雅关闭的两种方法(程序停止前做一些善后工作)
  8. 【来日复制粘贴】提取工作表和工作簿名称
  9. 【来日复制粘贴】用高级筛选和函数公式拆分数据列表
  10. Java 代码精简之道 侵删