Mockito作用

Mockito 是一个针对 Java 的单元测试模拟框架,是为了简化单元测试过程中测试上下文 ( 或者称之为测试驱动函数以及桩函数 ) 的搭建而开发的工具。在有这些模拟框架之前,为了编写某一个函数的单元测试,程序员必须进行十分繁琐的初始化工作,以保证被测试函数中使用到的环境变量以及其他模块的接口能返回预期的值,有些时候为了单元测试的可行性,甚至需要牺牲被测代码本身的结构。单元测试模拟框架则极大的简化了单元测试的编写过程:在被测试代码需要调用某些接口的时候,直接模拟一个假的接口,并任意指定该接口的行为。这样就可以大大的提高单元测试的效率以及单元测试代码的可读性。

添加maven依赖

      <dependency><groupId>org.mockito</groupId><artifactId>mockito-all</artifactId><version>1.9.5</version><scope>test</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency>

1. 验证某些行为

 @Testpublic void verify_behaviour() {System.out.println("验证某些行为");// 模拟创建一个List对象List mock = mock(List.class);// 使用mock的对象mock.add(1);mock.clear();// 验证add(1)和clear()行为是否发生verify(mock).clear();verify(mock).add(1);}

2. 如何做一些测试桩

 @Testpublic void verify_stub() {System.out.println("如何做测试桩");// 你可以mock具体的类型,不仅只是接口LinkedList mockedList = mock(LinkedList.class);// 测试桩when(mockedList.get(0)).thenReturn("first");// 输出“first”System.out.println(mockedList.get(0));// 因为get(999) 没有打桩,因此输出nullSystem.out.println(mockedList.get(999));// 验证get(0)被调用的次数verify(mockedList).get(0);}

3. 参数匹配器

 @Testpublic void verify_matcher() {System.out.println("参数匹配器");// 你可以mock具体的类型,不仅只是接口LinkedList mockedList = mock(LinkedList.class);// 使用内置的anyInt()参数匹配器when(mockedList.get(anyInt())).thenReturn("element");// 使用自定义的参数匹配器( 在isValid()函数中返回你自己的匹配器实现 )when(mockedList.contains(argThat(new IsValid()))).thenReturn(true);// 输出elementSystem.out.println(mockedList.get(999));// 输出trueSystem.out.println(mockedList.contains(1));// 你也可以验证参数匹配器verify(mockedList).get(anyInt());}private class IsValid extends ArgumentMatcher<List>{@Overridepublic boolean matches(Object o) {return (int)o == 1 || (int)o == 2;}}

4. 验证函数的确切、最少、从未调用次数

 @Testpublic void verify_times() {System.out.println("验证函数的确切、最少、从未调用次数");LinkedList mockedList = mock(LinkedList.class);mockedList.add("once");mockedList.add("twice");mockedList.add("twice");mockedList.add("three times");mockedList.add("three times");mockedList.add("three times");// 下面的两个验证函数效果一样,因为verify默认验证的就是times(1)verify(mockedList).add("once");verify(mockedList, times(1)).add("once");// 验证具体的执行次数verify(mockedList, times(2)).add("twice");verify(mockedList, times(3)).add("three times");// 使用never()进行验证,never相当于times(0)verify(mockedList, never()).add("never happened");// 使用atLeast()/atMost()verify(mockedList, atLeastOnce()).add("three times");verify(mockedList, atLeast(2)).add("five times");verify(mockedList, atMost(5)).add("three times");}

5. 为返回值为void的函数通过Stub抛出异常

 @Testpublic void verify_exception() {System.out.println("为返回值为void的函数通过Stub抛出异常");LinkedList mockedList = mock(LinkedList.class);doThrow(new RuntimeException()).when(mockedList).clear();// 调用这句代码会抛出异常mockedList.clear();}

6. 验证执行顺序

 @Testpublic void verify_order() {System.out.println("验证执行顺序");// A. 验证mock一个对象的函数执行顺序List singleMock = mock(List.class);singleMock.add("was added first");singleMock.add("was added second");// 为该mock对象创建一个inOrder对象InOrder inOrder = inOrder(singleMock);// 确保add函数首先执行的是add("was added first"),然后才是add("was added second")inOrder.verify(singleMock).add("was added first");inOrder.verify(singleMock).add("was added second");// B. 验证多个mock对象的函数执行顺序List firstMock = mock(List.class);List secondMock = mock(List.class);firstMock.add("was called first");secondMock.add("was called second");// 为这两个Mock对象创建inOrder对象InOrder inOrder2 = inOrder(firstMock, secondMock);// 验证它们的执行顺序inOrder2.verify(firstMock).add("was called first");inOrder2.verify(secondMock).add("was called second");}

7. 确保交互操作不会执行在mock对象上

 @Testpublic void verify_interaction() {System.out.println("确保交互操作不会执行在mock对象上");List mockOne = mock(List.class);List mockTwo = mock(List.class);List mockThree = mock(List.class);mockOne.add("one");verify(mockOne).add("one");verify(mockOne,never()).add("two");//验证零互动行为verifyZeroInteractions(mockTwo,mockThree);}

8. 找出冗余的互动(即未被验证到的)

 @Testpublic void verify_redundant() {System.out.println("找出冗余的互动(即未被验证到的)");LinkedList mockedList = mock(LinkedList.class);mockedList.add("one");mockedList.add("two");verify(mockedList).add("one");// 下面的验证将会失败verifyNoMoreInteractions(mockedList);}

9. 使用注解来快速模拟对象

 @Mockprivate List mockList;@Testpublic void verify_shorthand() {System.out.println("使用注解来快速模拟对象");//必须初始化,要不然mockList的对象为NULLMockitoAnnotations.initMocks(this);mockList.add(1);verify(mockList).add(1);}

10. 为连续的调用做测试桩

 @Mockprivate List mockList;@Test(expected = RuntimeException.class)public void verify_consecutive(){System.out.println("为连续的调用做测试桩");//模拟连续调用返回期望值,如果分开,则只有最后一个有效when(mockList.get(0)).thenReturn(0);when(mockList.get(0)).thenReturn(1);when(mockList.get(0)).thenReturn(2);when(mockList.get(1)).thenReturn(0).thenReturn(1).thenThrow(new RuntimeException());assertEquals(2,mockList.get(0));assertEquals(2,mockList.get(0));assertEquals(0,mockList.get(1));assertEquals(1,mockList.get(1));//第三次或更多调用都会抛出异常mockList.get(1);}

11. 为回调做测试桩

 @Mockprivate List mockList;@Test(expected = RuntimeException.class)public void verify_callback() {System.out.println("为回调做测试桩");// 使用Answer来生成我们我们期望的返回when(mockList.get(anyInt())).thenAnswer(new Answer<Object>() {@Overridepublic Object answer(InvocationOnMock invocation) throws Throwable {Object[] args = invocation.getArguments();return "hello world:" + args[0];}});assertEquals("hello world:0", mockList.get(0));assertEquals("hello world:999", mockList.get(999));}

12. 监控真实对象

 @Testpublic void verify_spy(){System.out.println("监控真实对象");List list = new LinkedList();List spy = spy(list);// 你可以为某些函数打桩when(spy.size()).thenReturn(100);// 通过spy对象调用真实对象的函数spy.add("one");spy.add("two");// 输出第一个元素System.out.println(spy.get(0));// 因为size()函数被打桩了,因此这里返回的是100System.out.println(spy.size());// 交互验证verify(spy).add("one");verify(spy).add("two");}

13. 修改没有测试桩的调用的默认返回值

 @Testpublic void verify_unstubbed(){System.out.println("修改没有测试桩的调用的默认返回值");//mock对象使用Answer来对没有测试桩的调用返回默认期望值List mock = mock(List.class,new Answer() {@Overridepublic Object answer(InvocationOnMock invocation) throws Throwable {return 999;}});//下面的get(1)没有预设,通常情况下会返回NULL,但是使用了Answer改变了默认期望值assertEquals(999, mock.get(1));//下面的size()没有预设,通常情况下会返回0,但是使用了Answer改变了默认期望值assertEquals(999,mock.size());}

14. 为下一步的断言捕获参数

@Testpublic void verify_capturing() {System.out.println("为下一步的断言捕获参数");PersonDao personDao = mock(PersonDao.class);PersonService personService = new PersonService(personDao);ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);personService.update(1, "jack");verify(personDao).update(argument.capture());assertEquals(1, argument.getValue().getId());assertEquals("jack", argument.getValue().getName());}class Person {private int id;private String name;Person(int id, String name) {this.id = id;this.name = name;}public int getId() {return id;}public String getName() {return name;}}interface PersonDao {public void update(Person person);}class PersonService {private PersonDao personDao;PersonService(PersonDao personDao) {this.personDao = personDao;}public void update(int id, String name) {personDao.update(new Person(id, name));}}

15. 重置mock对象

 @Testpublic void verify_reset() {System.out.println("重置mocks对象");List list = mock(List.class);when(list.size()).thenReturn(10);list.add(1);assertEquals(10, list.size());// 重置mock,清除所有的互动和预设reset(list);assertEquals(0, list.size());}

单元测试工具之Mockito相关推荐

  1. 单元测试系列之五:Mock工具之Mockito实战

    更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢! 原文链接:http://www.cnblogs.com/zishi/p/6780719.html 在实际项目中写单 ...

  2. Mock工具之Mockito实战

    在实际项目中写单元测试的过程中我们会发现需要测试的类有很多依赖,这些依赖项又会有依赖,导致在单元测试代码里几乎无法完成构建,尤其是当依赖项尚未构建完成时会导致单元测试无法进行.为了解决这类问题我们引入 ...

  3. 单元测试Mock框架--Mockito

    文章目录 目前开发中,单元测试遇到的问题 解决方案--Mock Junit4 + Mockito: Mockito常用注解: Mockito常用方法: Tips: 总结 目前开发中,单元测试遇到的问题 ...

  4. 【软件测试】2021年软件测试领域常用工具总结(1)-抓包工具与单元测试工具篇

    前言 大家好,我是洋子,作为一名测试开发/软件测试工程师, 在进行软件测试的过程中,会用到测试工具去辅助测试,以提高测试工作的效率.今天就给大家介绍一下2021年软件测试领域当中的最流行,最实用的工具 ...

  5. Openstack_单元测试工具 tox

    目录 目录 扩展阅读 Openstack 的单元测试工具 单元测试工具使用流程 tox toxini 参考文章 扩展阅读 Python Mock的入门 Openstack 的单元测试工具 unitte ...

  6. 在.NET开发中的单元测试工具之(1)——NUnit

    NUnit介绍 NUnit是一个专门针对于.NET来写的单元测试框架,它是xUnit体系中的一员,在xUnit体系中还有针对Java的JUnit和针对C++的CPPUnit,在开始的时候NUnit和x ...

  7. python 单元测试 工具_Django单元测试工具test client使用详解

    The test client test client是一个python类,来模拟一个简单的"哑"浏览器,允许你来测试你的view函数.你可以使用test client完成下列事情 ...

  8. SAP UI5 初学者教程之二十七 - SAP UI5 应用的单元测试工具 QUnit 介绍试读版

    一套适合 SAP UI5 初学者循序渐进的学习教程 教程目录 SAP UI5 本地开发环境的搭建 SAP UI5 初学者教程之一:Hello World SAP UI5 初学者教程之二:SAP UI5 ...

  9. SAP UI5 应用开发教程之二十七 - SAP UI5 应用的单元测试工具 QUnit 介绍

    Jerry 在之前做 SAP UI5 标准开发和现在使用 Angular 开发 SAP Spartacus 应用时,我们团队的开发规范就是,每增添一个新的前端 feature,必须要用一个新增的单元测 ...

最新文章

  1. flask_sqlalchemy 多对多 关系 对中间表的操作
  2. SQL Server 扩展事件系列 (1 of 31) -- 扩展事件概述
  3. 安装tensorflow_gpu,无法定位程序输入点
  4. Nginx服务状态的监控
  5. 问题与事务跟踪系统jira中的版本管理
  6. Python 字典 get() 方法
  7. 全民免费吃鸡,驱动人生带你玩转PUBG
  8. How to work with Ant
  9. EVO工具在EUROC数据集TUM数据集,评测ORB-SLAM3和VINS-MONO
  10. Python进行拉勾网数据爬取框架与思路
  11. 关于GeForce Experience更新驱动显示图形驱动程序安装失败
  12. 【整理资料】空间信息网络通信协议
  13. 关于字符串子串 真子串 非空子串 非空真子串的求解方法
  14. 论“GPL就是给软件开发者们准备的坑”
  15. 数据恢复如何看异或问题
  16. 流年如风卷起梅花飘零的记忆
  17. 【图像处理】像素坐标系、像平面坐标系、相机坐标系、世界坐标系、内参矩阵、外参矩阵
  18. 史上最爆笑的真心话大冒险
  19. 工业物联网发展现状如何
  20. 【学习笔记】C++语言程序设计(郑莉):继承与派生

热门文章

  1. 如何成为一名专业的云渗透测试工程师
  2. Python调用手机摄像头
  3. (PMP)第13章-----项目相关方管理
  4. oracle connect by优化小探
  5. SiT3807:高性能单端压控振荡器VCXO
  6. Web 应用程序防火墙 (WAF) 相关知识介绍
  7. 启方半导体基于二代0.13微米嵌入式闪存技术的汽车半导体工艺即将量产
  8. Spark系列 (五)Spark-GraphX的基本介绍与算子的简单使用---网络红人排名实例分解
  9. 分类梨和苹果的两种方法
  10. 使用Docker隔离wps