- 浏览: 240953 次
- 性别:
- 来自: 北京
最新评论
-
MCLoginandPwd:
分享一款可视化的工具来生成,拖拽控件,选择数据源就生成了htt ...
使用Mybatis Generator自动生成Mybatis相关代码 -
zxt1985:
我的博客里有下载链接
使用google-diff-match-patch比较文件 -
astarring:
XML配置的方式非常灵活,不过对于新手来说有点困难。我专门写了 ...
使用Mybatis Generator自动生成Mybatis相关代码 -
astarring:
XML配置的方式非常灵活,不过对于新手来说有点困难。我专门写了 ...
使用Mybatis Generator自动生成Mybatis相关代码 -
hw910206:
...
使用Mockito进行单元测试【1】——mock and verify
1. 为什么使用Mockito来进行单元测试?
回答这个问题需要回答两个方面,第一个是为什么使用mock?mock其实是一种工具的简称,他最大的功能是帮你把单元测试的耦合分解开,如果你的代码对另一个类或者接口有依赖,它能够帮你模拟这些依赖,并帮你验证所调用的依赖的行为。
比如一段代码有这样的依赖:
当我们需要测试A类的时候,如果没有mock,则我们需要把整个依赖树都构建出来,而使用mock的话就可以将结构分解开,像下面这样:
还有一个问题是mock工具那么多,为什么我们要用mockito呢?原因很简单:他非常好用!
他使用执行后验证的模型,语法更简洁并且更加贴近程序员的思考方式,能够模拟类而不仅仅是接口等等。总之如果你想使用mock的话,试用mockito,你不会后悔的:)
引用的图摘自http://www.theserverside.com/news/1365050/Using-JMock-in-Test-Driven-Development,那里对mock的使用有很好的介绍。
http://www.sizovpoint.com/2009/03/java-mock-frameworks-comparison.html是一篇非常好的mock工具比较的文章,我就是从它认识的mockito,他也有对mock使用的精彩介绍。
还有一篇文章总结了mockito的好处:http://java.dzone.com/articles/mockito-pros-cons-and-best
当然,要想真正了解mockito的好处,就必须写写代码练习一下了。
2. Mockito使用实例
这里的代码基本都是从http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html
摘出来的,然后加上了自己的一些学习验证,这个网页挺重要的,会多次提到,以后就简称”网页“了。让我们通过这些实例来看看mockito的强大功能吧:
1. 让我们验证一些行为吧
//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是怎么做到的:
// 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的值。
像下面这段代码,你猜会打印什么?
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】了
// 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:
// correct verify(mock).someMethod(anyInt(), anyString(), eq("third argument")); // will throw exception verify(mock).someMethod(anyInt(), anyString(), "third argument");
4. 继续讨论Verification
前面的例子都是和网页上的例子一一对应的,现在我们集中讨论一下mockito在verify上提供的强大功能,大部分例子都很简单,所以我基本就是简单的罗列:
# 验证方法被调用的次数 网页例子4
//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
// 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
//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
//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的实力的;-)
发表评论
-
使用Mockito进行单元测试【2】—— stub 和 高级特性
2012-03-17 18:39 13520一篇中介绍了Mockito的基本信息,现在接着介绍Mockit ... -
使用google-diff-match-patch比较文件
2011-08-03 10:20 17376要对文本文件的进行比 ... -
java 的 MD5编码处理
2011-07-13 09:19 2949当需要对一个大文件计算MD5校验和时,JDK提供的方法速度是非 ... -
结合Spring使用Mybatis Generator生成的代码
2010-11-24 19:49 13912本文将简要介绍怎样利用Spring 整合 Mybatis Ge ... -
使用Mybatis Generator自动生成Mybatis相关代码
2010-11-21 21:25 99147本文将简要介绍怎样利用Mybatis Generator自动生 ... -
将 java.util.Properties 作为参数传入Spring [初级]
2010-11-11 13:18 4815在一个应用中,需要将 java.util.Properties ... -
Hudson java.home 设定
2010-08-20 19:56 3295在学习使用Hudson进行持续集成时,总是报这样的错误: c ... -
Java properties配置资源文件处理
2010-07-28 13:21 4819除了自己实现java文本处理properties配置资源文件这 ... -
使用Guice依赖注入实现工厂模式[5]——Guice的Scope
2010-07-26 21:20 1951Notice: 本文作者只是设 ... -
使用Guice依赖注入实现工厂模式[4]——Factory Method 模式
2010-07-26 21:17 1476Notice: 本文作者只是设计模式、Guice和依赖注入的初 ... -
使用Guice依赖注入实现工厂模式[3]——Builder 模式
2010-07-26 21:12 1483Notice: 本文作者只是设计模式、Guice和依赖注入的初 ... -
使用Guice依赖注入实现工厂模式[2]——Abstract Factory 模式
2010-07-26 21:08 1920otice: 本文作者只是设计模式、Guice和依赖注入的初学 ... -
使用Guice依赖注入实现工厂模式[1]——Simple Factory 模式
2010-07-26 21:00 2263Notice: 本文作者只是设计模式、Guice和依赖注入的初 ... -
StackOverflowError on SqlMapClientBuilder.buildSqlMapClient
2010-07-23 18:36 1424在使用ibatis的时候,出现了这样的错误。原因是引入了两个不 ... -
AttributeError: 'TracError' object has no attribute 'acctmgr'
2010-07-23 18:29 1794使用AccountManager 进行用户管理的时候报了这样的 ... -
trac简易安装指南
2010-07-08 16:43 1862最权威的安装指南当然要参照 trac 的官方网站 http:/ ... -
测试辅助工具 hamcrest
2009-12-24 13:44 5214用了JUnit有一段时间了,竟然从来没有用过assertTha ... -
从iBATIS Hibernate 去日志依赖 看 模块化Java
2009-12-17 17:30 1485前几天看了一篇文章, ...
相关推荐
虽然测试分为单元测试,集成测试,系统测试等等,但是作为开发,我们可能不需要做这么多的测试(有时甚至不做……)接下来就说说和开发息息相关的单元测试以及集成测试。 单元测试就是模块测试,我的理解一个模块...
spring集成TestNG与Mockito框架单元测试方法,方便学习者能快速上手如何单测,对自己的代码能够有质量保证。
简单的Mockito 使用Mockito进行单元测试 参考: :
本篇文章主要介绍了基于Springboot+Junit+Mockito做单元测试的示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
spring集成TestNG与Mockito框架单元测试方法
包含 Junit + Hamcrest + Mockito 单元测试涉及到的三个jar包,分别是junit.jar、hamcrest-2.2.jar、mockito-core-3.2.4.jar
mockito junit 单元测试 mockito junit 单元测试
主要介绍了Java mockito单元测试实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
今天小编就为大家分享一篇关于Spring Boot单元测试中使用mockito框架mock掉整个RedisTemplate的示例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
Animal-Info:该项目将完成:导航-使用Dock的Jetpack MVVM改造调色板库数据绑定依赖性注入使用Mockito进行单元测试
内容概要:参考Mockito官方API文档,实践框架每个特性。 适合人群:Mockito入门人员以及想全面熟悉Mockito特性的人员,做到了开箱即用。...使用建议:使用前安装好Maven及Java即可,推荐使用VSCode编辑。
特别是使用 Kotlin(需要使用 mockito-inline)和 PowerMock(这会进一步加剧问题)的任何人都希望将其添加到他们所有的测试类中以避免大量内存泄漏。 想获得世界范围的知名度并建立 OSS 贡献者的永恒名声吗? 使用...
单元测试 使用Mockito和EasyMock进行样本单元测试
本文档ppt讲述了软件测试及单元测试的概念及区别、Junit框架概念及基本应用,并有详细的代码示例、异常测试的概念的测试代码、 超时测试的概念及测试代码、忽略测试的概念及测试代码、Mock学习及前后端代码调试、...
Mockito+junit5搞定单元测试
使用在springboot项目中使用powermock-mockito进行单元测试,演示mock static、private、whenNew、exception的测试。 注意 示例使用spring-boot 2.0.3.RELEASE 它间接引用 junit-4.12 mockito-core-2.15.0 但是官网...
单元测试工具mockito代码使用示例 文章地址 https://blog.csdn.net/qq_37813031/article/details/104557376
Mockito 是单元测试中的一种常用技术,掌握Mockito对单元测试有重要影响
在具体的使用场景中,例如,对于一些不容易构造或者获取的对象(如HttpServletRequest必须在Servlet容器中才能构造出来,或者JDBC中的ResultSet对象),Mockito可以创建一个虚拟的对象(即Mock对象)进行测试。...
Mocks or mock objects simulate the behavior of complex, real (nonmock) objects and are therefore useful when a real object is impractical or impossible to incorporate into a unit test. They provide:...