Mockito 的使用
转自:Mockito 中文文档 ( 2.0.26 beta )
参数匹配器
Argument Matcher(参数匹配器)

@Test
public void argumentMatchersTest(){
List<String> mock = mock(List.class);
when(mock.get(anyInt())).thenReturn("Hello").thenReturn("World");
String result=mock.get(100)+" "+mock.get(200);
verify(mock,times(2)).get(anyInt());
assertEquals("Hello World",result);
}


@Test
public void argumentMatchersTest(){
Map mapMock = mock(Map.class);
when(mapMock.put(anyInt(), anyString())).thenReturn("world");
mapMock.put(1, "hello");
verify(mapMock).put(anyInt(), eq("hello"));
}

在最后的验证时如果只输入字符串”hello”是会报错的,必须使用Matchers类内建的eq方法。如果将anyInt()换成1进行验证也需要用eq(1)。
自定义匹配器-ArgumentMatcher抽象类
自定义参数匹配器的时候需要继承ArgumentMatcher抽象类,它实现了Hamcrest框架的Matcher接口,定义了describeTo方法,所以我们只需要实现matches方法在其中定义规则即可。
下面自定义的参数匹配器是匹配size大小为2的List:
class IsListOfTwoElements extends ArgumentMatcher<List> {
@
public boolean matches(Object list) {
return ((List) list).size() == 2;
}
}
@Test
public void argumentMatchersTest(){
List mock = mock(List.class);
when(mock.addAll(argThat(new IsListOfTwoElements()))).thenReturn(true);
mock.addAll(Arrays.asList("one", "two", "three"));
verify(mock).addAll(argThat(new IsListOfTwoElements()));
}
argThat(Matcher<T> matcher)方法用来应用自定义的规则,可以传入任何实现Matcher接口的实现类。上例中在stubbing和verify addAll方法时通过argThat(Matcher<T> matcher),传入了自定义的参数匹配器IsListOfTwoElements用来匹配size大小为2的List。因为例子中传入List的元素为三个,所以测试将失败。
较复杂的参数匹配将会降低测试代码的可读性。有时实现参数对象的equals()方法是个不错的选择(Mockito默认使用equals()方法进行参数匹配),它可以使测试代码更为整洁。另外,有些场景使用参数捕获器(ArgumentCaptor)要比自定义参数匹配器更加合适。
如何捕获 mock 方法的调用参数
Mockito以java代码风格的形式来验证参数值 : 即通过使用equals()函数。这也是我们推荐用于参数匹配的方式,因为这样会使得测试代码更简单、简洁。在某些情况下,当验证交互之后要检测真实的参数值时这将变得有用。例如 :
@Test
public void captureNonGenericArgument() {
UserDao userDao = Mockito.mock(UserDao.class);
UserService userService = new UserService(userDao); userService.saveUser(new User(null, "Yanbin")); ArgumentCaptor<User> argumentCaptor = ArgumentCaptor.forClass(User.class);
verify(userDao, times(1)).save(argumentCaptor.capture()); assertEquals("Yanbin", argumentCaptor.getValue().name);
assertEquals("Chicago", argumentCator.getValue().city); //可断言捕获参数的更多特征
从面对被捕获参数 argumentCaptor.getValue() 的断言可看出它比 argThat() 的优势,argThat() 无法告诉我们不匹配的细节
警告 : 我们建议使用没有测试桩的ArgumentCaptor来验证,因为使用含有测试桩的ArgumentCaptor会降低测试代码的可读性,因为captor是在断言代码块之外创建的。另一个好处是它可以降低本地化的缺点,因为如果测试桩函数没有被调用,那么参数就不会被捕获。总之,ArgumentCaptor与自定义的参数匹配器相关(可以查看ArgumentMatcher类的文档 )。这两种技术都能用于检测外部传递到Mock对象的参数。然而,使用ArgumentCaptor在以下的情况下更合适 :
- 自定义不能被重用的参数匹配器
- 你仅需要断言参数值
我们同样可以在打桩的时候捕获参数,如
ArgumentCaptor<User> argumentCaptor = argumentCaptor.forClass(User.class);
when(userDao.findUserLike(argumentCaptor.capture)).thenReturn(Mockito.mock(User.class)); assertEquals("Yanbin", argumentCaptor.getValue().name);
不能以这种方式在打桩的时候捕获参数:
when(userDao.findUserLike(argumentCaptor.capture)).thenReturn(getUser(argumentCaptor.getValue()));
否则会报错:

出错位置在打桩的地方。记住打桩并不等于异步调用,它返回的是个固定值!
Mockito 的使用的更多相关文章
- Junit mockito 测试Controller层方法有Pageable异常
1.问题 在使用MockMVC+Mockito模拟Service层返回的时候,当我们在Controller层中参数方法调用有Pageable对象的时候,我们会发现,我们没办法生成一个Pageable的 ...
- Junit mockito解耦合测试
Mock测试是单元测试的重要方法之一. 1.相关网址 官网:http://mockito.org/ 项目源码:https://github.com/mockito/mockito api:http:/ ...
- Android 单元测试(junit、mockito、robolectric)
1.运用JUnit4 进行单元测试 首先在工程的 src 文件夹内创建 test 和 test/java 文件夹. 打开工程的 build.gradle(Module:app)文件,添加JUnit4依 ...
- Mockito Hello World
Mockito Hello World 项目配置 IDE是Intellij IDEA,用gradle配置项目. 新建一个Java项目,gradle中需要有这个: repositories { jc ...
- mockito使用心得
前提:pom引用<dependency> <groupId>junit</groupId> <artifactId>junit</artifact ...
- Mock之easymock, powermock, and mockito
easymock, powermock, and mockito Easymock Class Mocking Limitations To be coherent with interface mo ...
- 用Mockito mock普通的方法
上面的例子是很理想化的状态,但是在实际的开发中,我们需要经常调用一些依赖特定环境的函数或者调用同事写的代码,而同事仅提供了接口.这个时候就需要利用Mockito来协助我们完成测试. 当然,你可以选择e ...
- mock测试框架Mockito
无论是敏捷开发.持续交付,还是测试驱动开发(TDD)都把单元测试作为实现的基石.随着这些先进的编程开发模式日益深入人心,单元测试如今显得越来越重要了.在敏捷开发.持续交付中要求单元测试一定要快(不能访 ...
- Mockito自定义verify参数Matcher
在TDD开发中,也许我们会遇见对一些重要的无返回值的行为测试,比如在用户的积分DB中增加用户的积分,这个行为对于我们的业务具有重要的价值,所以我们也希望能测试覆盖这部分业务价值.这个时候我们就得使用m ...
- Mockito学习资料
官网:http://mockito.org/ https://dzone.com/refcardz/mockito
随机推荐
- 005.KVM日常管理2-virt管理
一 安装管理工具 [root@kvm-host ~]# rpm -qa|grep libguestfs-tools #查看相关管理工具,若没安装,可使用yum安装. 二 日常管理 2.1 命令格式 ...
- rabbitmq学习(三) —— 工作队列
工作队列,又称任务队列,主要思想是避免立即执行资源密集型任务,并且必须等待完成.相反地,我们进行任务调度,我们将一个任务封装成一个消息,并将其发送到队列.工作进行在后台运行不断的从队列中取出任务然后执 ...
- HTML Agility Pack:簡單好用的快速 HTML Parser
HTML Agility Pack:簡單好用的快速 HTML Parser Codeplex 軟體套件(Package)資訊 套件名稱 HTML Agility Pack 作者 Simon Mouri ...
- BZOJ.4946.[NOI2017]蔬菜(贪心 离线)
题目链接 因为有删除,考虑倒序处理某个p的询问. 那么每天删除xi的蔬菜就变成了每天运来xi的蔬菜.那么我们取当前最优的即可,早取晚取都一样,不需要留给后面取,还能给后面更优的留出空间. 这样就只需考 ...
- hdu 4612 边双联通 ***
题意:有N 个点,M条边,加一条边,求割边最少.(有重边) 链接:点我 先求双连通分量,缩点形成一个生成树,然后求这个的直径,割边-直径即是答案 #pragma comment(linker, &qu ...
- Redis和数据库 数据同步问题
Redis和数据库同步问题 缓存充当数据库 比如说Session这种访问非常频繁的数据,就适合采用这种方案:当然了,既然没有涉及到数据库,那么也就不会存在一致性问题: 缓存充当数据库热点缓存 读操作 ...
- 2013-2014 ACM-ICPC, NEERC, Southern Subregional Contest Problem C. Equivalent Cards 计算几何
Problem C. Equivalent Cards 题目连接: http://www.codeforces.com/gym/100253 Description Jane is playing a ...
- hdu 5753 Permutation Bo 水题
Permutation Bo 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5753 Description There are two sequen ...
- windows servier2008+virtualenv下部署Flask (IIS+wfastcgi)
由于业务只有一台windows server2008的服务器,一般的nginx+uwsgi的部署方式不行,以下记录部署过程,本文参考自:https://www.cnblogs.com/xiaolecn ...
- 【Go命令教程】10. go fix 与 go tool fix
命令 go fix 会把指定 代码包 的所有 Go 语言源码文件中的旧版本代码修正为新版本的代码.这里所说的版本即 Go 语言的版本.代码包的所有 Go 语言源码文件不包括其子代码包(如果有的话)中的 ...