本文转自:http://qiuguo0205.iteye.com/blog/1443344

1. 为什么使用Mockito来进行单元测试?

回答这个问题需要回答两个方面,第一个是为什么使用mock?mock其实是一种工具的简称,他最大的功能是帮你把单元测试的耦合分解开,如果你的代码对另一个类或者接口有依赖,它能够帮你模拟这些依赖,并帮你验证所调用的依赖的行为。

比如一段代码有这样的依赖:

当我们需要测试A类的时候,如果没有mock,则我们需要把整个依赖树都构建出来,而使用mock的话就可以将结构分解开,像下面这样:

还有一个问题是mock工具那么多,为什么我们要用mockito呢?原因很简单:他非常好用!

他使用执行后验证的模型,语法更简洁并且更加贴近程序员的思考方式,能够模拟类而不仅仅是接口等等。总之如果你想使用mock的话,试用mockito,你不会后悔的:)

当然,要想真正了解mockito的好处,就必须写写代码练习一下了。

2. Mockito使用实例

摘出来的,然后加上了自己的一些学习验证,这个网页挺重要的,会多次提到,以后就简称”网页“了。让我们通过这些实例来看看mockito的强大功能吧:

1. 让我们验证一些行为吧

Java代码  

//Let's import Mockito statically so that the code looks clearer

import static org.mockito.Mockito.*;

//mock creation

List mockedList = mock(List.class);

// using mock object

mockedList.add("one");

mockedList.clear();

mockedList.add("3"); // no verify? OK

// verification

verify(mockedList).add("one");

verify(mockedList).clear();

// verify(mockedList).add("2"); // this will throw an exception

首先通过这段代码介绍什么是mock:首先使用Mockito的静态方法mock,我们就可以创建一个类的mock实例,这个mock实例拥有这个List的所有方法接口,并且给这些方法以最基本的实现:如果是返回void,他什么都不做,否则他就返回null或0等基本类型的值。比如中间的三句调用了mock的方法,即使将来不验证也没有任何关系。

在验证阶段,当我们验证这个mock的方法add("one")是否被调用的时候,他不会抛出异常,因为我们确实调用了这个方法,但是当我们验证它是否调用add("2")的时候,就会抛出异常,说明我们没有调用过这个方法,此时的测试就会失败。

所以验证的意思是”查看我们到底有没有调用过mock的这个方法“。

2. 它能提供桩[stub]测试吗?

相信这样的场景我们都遇到过,有一个方法的输入是一个List,在这个方法中我们遍历这个List,读取数据,做相应的操作。往常我们可能需要自己创建一个ArrayList,并且将需要的测试的参数add进list中,这样就可以分别进行测试了。下面看看使用mockito是怎么做到的:

Java代码  

// You can mock concrete classes, not only interfaces

LinkedList mockedList = mock(LinkedList.class);

// stubbing

when(mockedList.get(0)).thenReturn("first");

when(mockedList.get(1)).thenThrow(new RuntimeException());

// following prints "first"

System.out.println(mockedList.get(0));

// following throws runtime exception

System.out.println(mockedList.get(1));

// following prints "null" because get(999) was not stubbed

System.out.println(mockedList.get(999));

// Although it is possible to verify a stubbed invocation, usually it's just redundant

// See http://monkeyisland.pl/2008/04/26/asking-and-telling

verify(mockedList, atLeast(2)).get(0);

首先我们可以看到mockito是可以mock类而不仅仅是接口的,而stub的语法也非常接近人的阅读习惯:when(mockedList.get(0)).thenReturn("first"); 当调用get(0)的时候返回"first"。

这里需要注意以下几点:

【1】mock实例默认的会给所有的方法添加基本实现:返回null或空集合,或者0等基本类型的值。

【2】当我们连续两次为同一个方法使用stub的时候,他只会只用最新的一次。

【3】一旦这个方法被stub了,就会一直返回这个stub的值。

像下面这段代码,你猜会打印什么?

Java代码  

when(mockedList.get(0)).thenReturn("first");

when(mockedList.get(0)).thenReturn("oops");

System.out.println(mockedList.get(0));

System.out.println(mockedList.get(0));

3. 参数匹配

下面我们看看mockito强大的参数匹配机制,当mockito执行verify的时候,它实际上对参数执行的是自然地java方式——equals方法。有事我们需要对参数进行灵活匹配的时候就可以用到”参数匹配器“【argument matchers】了

Java代码  

// stubbing using built-in anyInt() argument matcher

when(mockedList.get(anyInt())).thenReturn("element");

// following prints "element"

System.out.println(mockedList.get(999));

// you can also verify using an argument matcher

verify(mockedList).get(anyInt());

这里的anyInt是mockito内建的众多方法之一,其他可以参考mockito主页上的信息,你也可以调用hamcrest的matchers。

警告:若方法中的某一个参数使用了matcher,则所有的参数都必须使用matcher:

Java代码  

// correct

verify(mock).someMethod(anyInt(), anyString(), eq("third argument"));

// will throw exception

verify(mock).someMethod(anyInt(), anyString(), "third argument");

4. 继续讨论Verification

前面的例子都是和网页上的例子一一对应的,现在我们集中讨论一下mockito在verify上提供的强大功能,大部分例子都很简单,所以我基本就是简单的罗列:

# 验证方法被调用的次数 网页例子4

Java代码  

//using mock

mockedList.add("once");

mockedList.add("twice");

mockedList.add("twice");

mockedList.add("three times");

mockedList.add("three times");

mockedList.add("three times");

//following two verifications work exactly the same - times(1) is used by default

verify(mockedList).add("once");

verify(mockedList, times(1)).add("once");

//exact number of invocations verification

verify(mockedList, times(2)).add("twice");

verify(mockedList, times(3)).add("three times");

//verification using never(). never() is an alias to times(0)

verify(mockedList, never()).add("never happened");

//verification using atLeast()/atMost()

verify(mockedList, atLeastOnce()).add("three times");

verify(mockedList, atLeast(2)).add("five times");

verify(mockedList, atMost(5)).add("three times");

# 按顺序验证  网页例子6

Java代码  

// A. Single mock whose methods must be invoked in a particular order

List singleMock = mock(List.class);

//using a single mock

singleMock.add("was added first");

singleMock.add("was added second");

//create an inOrder verifier for a single mock

InOrder inOrder = inOrder(singleMock);

//following will make sure that add is first called with "was added first, then with "was added second"

inOrder.verify(singleMock).add("was added first");

inOrder.verify(singleMock).add("was added second");

// B. Multiple mocks that must be used in a particular order

List firstMock = mock(List.class);

List secondMock = mock(List.class);

//using mocks

firstMock.add("was called first");

secondMock.add("was called second");

//create inOrder object passing any mocks that need to be verified in order

InOrder inOrder = inOrder(firstMock, secondMock);

//following will make sure that firstMock was called before secondMock

inOrder.verify(firstMock).add("was called first");

inOrder.verify(secondMock).add("was called second");

// Oh, and A + B can be mixed together at will

# 确保某些方法没有被调用  网页例子7

Java代码  

//using mocks - only mockOne is interacted

mockOne.add("one");

//ordinary verification

verify(mockOne).add("one");

//verify that method was never called on a mock

verify(mockOne, never()).add("two");

//verify that other mocks were not interacted

verifyZeroInteractions(mockTwo, mockThree);

# 从前面的例子我们可以看到,能够很容易地找到冗余的调用  网页例子8

Java代码  

//using mocks

mockedList.add("one");

mockedList.add("two");

verify(mockedList).add("one");

//following verification will fail

verifyNoMoreInteractions(mockedList);

OK,看过Mockito的 mock 和 verify的能力,你可能已经喜欢上Mockito了,不过这只是Mockito强大功能的一部分,下一篇接着翻译我个人用的最多的stub的功能,真的不可错过,看完之后你绝对能够惊叹Mockito的实力的;-)

java mock verify_使用Mockito进行单元测试【1】——mock and verify[转]相关推荐

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

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

  2. Mock(Mockito)单元测试实战

    文章目录 1.什么是Mock? 1.1. Mockito中文文档 1.2.Mockito基本使用方法简介 初始化MockMvc对象(BaseUnitTest) 初始化Mock框架 测试方法 2.0 m ...

  3. Mock工具之Mockito实战

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

  4. 单元测试与 Mock 方法

    Mock 方法是单元测试中常见的一种技术,它的主要作用是模拟一些在应用中不容易构造或者比较复杂的对象,从而把测试与测试边界以外的对象隔离开. 编写自定义的 Mock 对象需要额外的编码工作,同时也可能 ...

  5. mockito mock void方法_纯干货,浅谈Mockito在单元测试中的实际应用

    本文接上文"接口方没写代码,对接方只能停工吗?",在这里简单介绍Mockito在单元测试中的实际应用.本文使用场景较单一,如有雷同,不甚荣幸,闲言少叙,开门见山.本文将使用mock ...

  6. Java单元测试(Junit+Mock+代码覆盖率)

    单元测试是编写测试代码,用来检测特定的.明确的.细颗粒的功能.单元测试并不一定保证程序功能是正确的,更不保证整体业务是准备的. 单元测试不仅仅用来保证当前代码的正确性,更重要的是用来保证代码修复.改进 ...

  7. mockito mock void方法_使用 Junit + Mockito 实践单元测试!

    一.前言 相信做过开发的同学,都多多少少写过下面的代码,很长一段时间我一直以为这就是单元测试... @SpringBootTest @RunWith(SpringRunner.class) publi ...

  8. java junit mock_使用Mockito进行Java的Mock测试

    测试替身 dummy用于传递,不会真正使用,例如用于填充的方法的参数列表. Fake有简单实现,但通常被简化,比如在内存数据库,而不是真正的数据库中使用. Stub是接口或类中部分实现,测试时使用其实 ...

  9. Java单元测试使用mock【转载】

    1.什么是Mock? mock是在测试过程中,对于一些不容易构造/获取的对象,创建一个mock对象来模拟对象的行为.比如说你需要调用B服务,可是B服务还没有开发完成,那么你就可以将调用B服务的那部分给 ...

最新文章

  1. iOS 蓝牙开发和注意点
  2. Spring-Spring 开发环境搭建及HelloSpring
  3. Mac OS X下配置Cocos2d-x for Android(Eclipse)IOS(Xcode)开发环境
  4. 全能无线渗透测试工具,一个LAZY就搞定了
  5. geotools学习(一)IntelliJ IDEA搭建快速入门示例.pdf
  6. 324. Wiggle Sort II | 324. 摆动排序 II(降序穿插)
  7. Android官方开发文档Training系列课程中文版:线程执行操作之线程间通讯
  8. 没有光芯片,何谈 5G 与 AI !
  9. PHP中输出本地时间
  10. 帝国CMS操作类型一览表
  11. 送你一份价值5800元的技术干货PPT | 技术管理者工作坊强势来袭!
  12. Process Explorer简易图文教程(下)
  13. 山东大学舆情分析系统项目结题总结
  14. 机器学习——逻辑回归算法代码实现
  15. 2007年日历带农历表_2007年农历阳历表 2007年农历表 2007年日历表
  16. 12.2 关闭DLM 自动收集统计信息 (SCM0)ORA-00600之[ksliwat: bad wait time]
  17. 图片按指定比例缩放并压缩至指定大小,解决保存图片文件体积过大bug。
  18. 2022年9月青少年C/C++软件编程(四级)等级考试试卷及答案解析
  19. android ios图片丢失,如何恢复iPhone、安卓智能手机上误删、丢失的图片?
  20. 搞定机械工程专业毕业设计选题推荐

热门文章

  1. 小白打boss之路——2020fintech训练营数据赛道
  2. ec12编码器电路图_光电编码器电路图.DOC
  3. clCreateBuffer中cl_mem_flags参数解释
  4. SAR ADC 介绍 核芯CL1606/CL1689/CL1680 替代AD7607/AD7689/AD1980
  5. 快速上手百度大脑人体关键点识别
  6. 编程实用工具大全(二)(前后端皆可用,不来看看?)
  7. 20单元——学习正解表达式及学习实践 Shell script
  8. 【React】1128- 如何在 React 组件中优雅的实现依赖注入
  9. Tencent后台开发Java岗二面:Java中高级核心知识全面解析
  10. 竞价网站服务器,派代网-竞价网站被攻击的完美解决方法