public interface DBAccess {
int delete(String moi,String moc) throws Exception;
void create(String moi,String moc,Map<String,Object> attributes)throws Exception;
List<Map<String, Object>> select(String moi,String moc,String[] attributes) throws Exception;
int update(String moi,String moc,Map<String,Object> attributes)throws Exception;
}

Mock:

        dbAccess=mock(DBAccess.class);
Collection<String> attrs=anyCollectionOf(String.class);
when(dbAccess.select(anyString(), anyString(),attrs.toArray(new String[attrs.size()]) )).thenReturn(resultList); verify(dbAccess,times(wantedNumberOfInvocations)).create(anyString(), anyString(), anyMapOf(String.class, Object.class));

回到官网:http://mockito.org/,打开documentation可以看到原文。

强烈建议不熟悉Mockito的同学先看看我写的Mockito(一)入门篇和(二)实例篇之后再来看这篇文章。

因为只有看了前两篇文章才明白mockito的本质以及该如何使用它。

下面是按原文 翻译+注释 的对Mockito全部功能的介绍。

1, 使用mockito验证行为。

//首先要importMockito.

import static org.mockito.Mockito.*;

//mock creation

List mockedList = mock(List.class);

//using mock object

mockedList.add("one");

mockedList.clear();

//验证add方法是否在前面被调用了一次,且参数为“one”。clear方法同样。

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

verify(mockedList).clear();

//下面的验证会失败。因为没有调用过add("two")。

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

原文中的一句话很重要:Once created, mock will remember all interactions.所以mockito知道前面是否调用过某方法。

2, 使方法调用返回期望的值。也被称为stubbing

//You can mock concrete classes, not only interfaces

LinkedList mockedList = mock(LinkedList.class);

//stubbing。当get(0)被调用时,返回"first". 方法get(1)被调用时,抛异常。

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));

默认情况下,对于所有有返回值且没有stub过的方法,mockito会返回相应的默认值。

对于内置类型会返回默认值,如int会返回0,布尔值返回false。对于其他type会返回null。

这里一个重要概念就是: mock对象会覆盖整个被mock的对象,因此没有stub的方法只能返回默认值。

//重复stub两次,则以第二次为准。如下将返回"second":

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

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

//如果是下面这种形式,则表示第一次调用时返回“first”,第二次调用时返回“second”。可以写n多个。

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

但是,如果实际调用的次数超过了stub过的次数,则会一直返回最后一次stub的值。

如上例,第三次调用get(0)时,则会返回"second".

3, 参数匹配

在上例中如果想实现get(任意整数)时,都返回“element”时,该怎么做呢?很简单。

//stubbing 使用了内置的anyint() matcher.

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

//因此除了anyint()之外,还有其他很多matcher。这里请参考原文。

//使用了matcher一样可以验证被调用的次数。

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

这里有一个限制就是,如果在调用方法时需要传入多个参数,其中一个参数使用了argument matcher,那么所有的参数必须都是matcher。

不可以matcher和实际的参数混着用。

这里也可以使用custom argument matcher。因为很多时候输入参数不是build-in 类型,而是我们自己写的一些类,或特殊对象。

这时要使用argument matcher,就必须订制特殊的matcher了。

下例是一个特殊的matcher的实例,这个matcher可以匹配任何file对象。

public class SayHiTest {

@Test
 public void testSayHi() throws Exception {
     File mock = mock(File.class); //首先mock File类。
     //注意new IsAnyFiles()并不是一个matcher,需要调用argThat(new IsAnyFiles()))才返回一个matcher。

//下句中stub:当调用renameTo方法时,返回false。该方法参数可以是任意file对象。

when(mock.renameTo(argThat(new IsAnyFiles()))).thenReturn(false); 
     mock.renameTo(new File("test"));

//下句verify renameTo方法被调用了一次,同时输入参数是任意file。
     verify(mock).renameTo(argThat(new IsAnyFiles()));
 }
}
 
class IsAnyFiles extends ArgumentMatcher<File> {
    public boolean matches(Object file) {
        return file.getClass() == File.class;
    }
 }

另外一个参数匹配的例子:

class IsSOAPMessage extends ArgumentMatcher<SOAPMessage> {

public boolean matches(Object soapMessage) {

 return (soapMessage instanceof SOAPMessage) || soapMessage==null;

}

}

//上面的macther不仅可以匹配任意的SOAPMessage对象,如果输入参数为空也可以匹配上。

这里说一下我犯过的一个错误。

我在做参数匹配的时候,没有考虑到输入参数为空的情况,导致matcher匹配不上,进而stub的行为无法生效。

其实在发现mock对象没有想自己想象的方式工作时,最好的方法就是debug进去,首先要先确定mock对象是不是真的传递进去了。然后再一步步的debug。

通常遇到的两种情况就是1,mock对象没有传递进去。2,参数没有匹配上。

4, 验证方法被调用了特定次数/至少x次/最多x次/从未被调用

//是否add("twice")被调用了两次。

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

//验证add("twice")被调用了至少一次。以及其他。

verify(mockedList, atLeastOnce()).add("twice");

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

verify(mockedList, atMost(5)).add("twice");

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

5, 调用方法时抛出异常

doThrow(new RuntimeException()).when(mockedList).clear();

后面还会再介绍几个类似的方法,例如doReturn()。

6, 验证顺序

//下面的代码验证firstMock先被调用,secondMock后被调用。

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

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

7, 验证mock之间没有相互作用6,7都不是很明白实际意义是什么。

8, 找到冗余的调用

用never()就可以实现,不多说

9, 使用@mock 定义mock。

之前都是使用mock()来模拟一个对象。用@mock是一个shorthand。

public class ArticleManagerTest {

@Mock private ArticleCalculator calculator;

@Mock private ArticleDatabase database;

@Mock private UserProvider userProvider;

private ArticleManager manager;

之后再继续介绍mockito复杂一点的功能。

http://blog.csdn.net/onlyqi/article/details/6544989

Mockito--完整功能介绍(转)的更多相关文章

  1. 升讯威微信营销系统开发实践:(3)功能介绍与此项目推广过程的一些体会( 完整开源于 Github)

    GitHub:https://github.com/iccb1013/Sheng.WeixinConstruction因为个人精力时间有限,不会再对现有代码进行更新维护,不过微信接口比较稳定,经测试至 ...

  2. .NET平台开源项目速览(13)机器学习组件Accord.NET框架功能介绍

    Accord.NET Framework是在AForge.NET项目的基础上封装和进一步开发而来.因为AForge.NET更注重与一些底层和广度,而Accord.NET Framework更注重与机器 ...

  3. 带你走近AngularJS - 基本功能介绍

    带你走近AngularJS系列: 带你走近AngularJS - 基本功能介绍 带你走近AngularJS - 体验指令实例 带你走近AngularJS - 创建自定义指令 ------------- ...

  4. CentOS以及Oracle数据库发展历史及各版本新功能介绍, 便于构造环境时有个对应关系

    CentOS版本历史 版本 CentOS版本号有两个部分,一个主要版本和一个次要版本,主要和次要版本号分别对应于RHEL的主要版本与更新包,CentOS采取从RHEL的源代码包来构建.例如CentOS ...

  5. WPF Step By Step 完整布局介绍

    WPF Step By Step 完整布局介绍 回顾 上一篇,我们介绍了基本控件及控件的重要属性和用法,我们本篇详细介绍WPF中的几种布局容器及每种布局容器的使用场景,当 然这些都是本人在实际项目中的 ...

  6. 3.Nginx常用功能介绍

    Nginx常用功能介绍 Nginx反向代理应用实例 反向代理(Reverse Proxy)方式是指通过代理服务器来接受Internet上的连接请求,然后将请求转发给内部网络上的服务器,并且从内部网络服 ...

  7. Python中模块之re的功能介绍

    re模块的功能介绍 1. 方法 match 从开头开始查找 方法:re.match(pattern,string,flags=0) 返回值:<class '_sre.SRE_Match'> ...

  8. Fiddler抓包使用教程-基本功能介绍

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/72932886 本文出自[赵彦军的博客] Fiddler 基本页面 会话列表功能介绍 ...

  9. 服务注册发现consul之一:consul介绍、安装、及功能介绍

    Consul 是一套开源的分布式服务发现和配置管理系统,由 HashiCorp 公司用 Go 语言开发.它具有很多优点.包括:基于 raft 协议,比较简洁: 支持健康检查, 同时支持 HTTP 和 ...

随机推荐

  1. arm中的ldr指令

    label .equ 0x53000000 ldr r0, label : 将0x53000000地址处的值放入r0中 ldr r0, =label : 将0x53000000付值给r0.

  2. 干I​n​l​a​y​的​生​产​过​程​

    •天线的组成 天线的材料有0.38PET和0.16以及0.3的铝箔组成. 倒封装 •将IC倒装在天线焊盘位置. •方法:先点胶水, 然后把IC对准焊盘(IC一面有凸点),通过热压把IC 固定在焊盘上. ...

  3. PhoneGap 3.0 安装

    PhoneGap 3.0  已经出来有一段时间了.3.0 提供了使用Node.js 安装,使用命令行创建.编译.运行项目.也就是可以抛弃eclipse,完全使用命令.记事本开发phonegap 项目了 ...

  4. LKD3

    第三章 进程1. Unix操作系统的抽象:进程和文件2. 进程包括两个因素:可运行代码,和资源(打开的文件,挂起的信号,内核内部数据,处理器状态,地址空间)3. 线程是进程中活动的对象.4. 线程有独 ...

  5. JavaScript中的字符串

    JavaScript字符串是JavaScript最重要的部分,可能比任何其他的数据类型都更多的用到. 所有的JavaScript对象共享的方法之一就是toString(). 字符串对象叫做String ...

  6. 面向对象之静态方法(static)和实例化方法的区别

    这是一个经常被时时提出来的问题,很多时候我们以为理解了.懂了,但深究一下,我们却发现并不懂. 方法是我们每天都在写得,很多程序员大多都使用实例化方法,而很少使用静态方法,问原因也说不出来所以然,或者简 ...

  7. 总线接口与计算机通信(四)USB外部总线(初级认识)

    USB简介   USB是英文Universal Serial BUS(通用串行总线)的缩写,是一个外部总线标准,用于规范电脑与外部设备的连接和通讯,是应用在PC领域的接口技术.USB接口支持设备的即插 ...

  8. linux 内核分析之list_head

    转自:http://www.cnblogs.com/riky/archive/2006/12/28/606242.html 一.链表数据结构简介 链表是一种常用的组织有序数据的数据结构,它通过指针将一 ...

  9. (IOS)CoreLocation 和 MapKit 的应用

    CoreLocation是控制GPS硬件获取地理坐标信息的系统类库,而MapKit是系统地图的工具包,将两者结合使用可以实现不同的地图功能. 1.CoreLocation 在CoreLocation中 ...

  10. IE11中[if lt IE 9]兼容性问题

    IE11不支持<!--[if lt IE 9]>  <![endif]--> ,蛋疼的IE!!!