Mockito 的使用

转自:Mockito 中文文档 ( 2.0.26 beta )

转自:手把手教你 Mockito 的使用

参数匹配器

Argument Matcher(参数匹配器)

Mockito通过equals()方法,来对方法参数进行验证。但是有时候我们需要更加灵活的参数需求,比如,匹配任何的String类型的参数等等。参数匹配器就是一个能够满足这些需求的工具。
Mockito框架中的Matchers类内建了很多参数匹配器,我们常用的Mockito对象就是继承自Matchers。比如anyInt()匹配任何int类型的参数,anyString()匹配任何字符串...
复制代码
@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); 
} 
复制代码
首先mock了List接口,然后用迭代的方式模拟了get方法的返回值,这里用了anyInt()参数匹配器来匹配任何的int类型的参数。所以当第一次调用get方法时输入任意参数为100方法返回”Hello”,第二次调用时输入任意参数200返回值”World”。
这里需要注意:
如果使用了参数匹配器,那么所有的参数需要由匹配器来提供,否则将会报错。假如我们使用参数匹配器stubbing了mock对象的方法,那么在verify的时候也需要使用它。如:
复制代码
@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:

 1 class IsListOfTwoElements extends ArgumentMatcher<List> { 
 2     @ 
 3     public boolean matches(Object list) {  
 4         return ((List) list).size() == 2;  
 5     }  
 6 }  
 7   
 8 @Test  
 9 public void argumentMatchersTest(){  
10     List mock = mock(List.class);  
11     when(mock.addAll(argThat(new IsListOfTwoElements()))).thenReturn(true);  
12        
13     mock.addAll(Arrays.asList("one", "two", "three"));  
14     verify(mock).addAll(argThat(new IsListOfTwoElements()));  
15 }

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()函数。这也是我们推荐用于参数匹配的方式,因为这样会使得测试代码更简单、简洁。在某些情况下,当验证交互之后要检测真实的参数值时这将变得有用。例如 :

 1 @Test
 2 public void captureNonGenericArgument() {
 3   UserDao userDao = Mockito.mock(UserDao.class);
 4   UserService  userService = new UserService(userDao);
 5  
 6   userService.saveUser(new User(null, "Yanbin"));
 7   
 8   ArgumentCaptor<User> argumentCaptor = ArgumentCaptor.forClass(User.class);
 9   verify(userDao, times(1)).save(argumentCaptor.capture());
10  
11    assertEquals("Yanbin", argumentCaptor.getValue().name);
12    assertEquals("Chicago", argumentCator.getValue().city); //可断言捕获参数的更多特征

从面对被捕获参数 argumentCaptor.getValue() 的断言可看出它比 argThat() 的优势,argThat() 无法告诉我们不匹配的细节

警告 : 我们建议使用没有测试桩的ArgumentCaptor来验证,因为使用含有测试桩的ArgumentCaptor会降低测试代码的可读性,因为captor是在断言代码块之外创建的。另一个好处是它可以降低本地化的缺点,因为如果测试桩函数没有被调用,那么参数就不会被捕获。总之,ArgumentCaptor与自定义的参数匹配器相关(可以查看ArgumentMatcher类的文档 )。这两种技术都能用于检测外部传递到Mock对象的参数。然而,使用ArgumentCaptor在以下的情况下更合适 :

  • 自定义不能被重用的参数匹配器
  • 你仅需要断言参数值

我们同样可以在打桩的时候捕获参数,如

1 ArgumentCaptor<User> argumentCaptor = argumentCaptor.forClass(User.class);
2 when(userDao.findUserLike(argumentCaptor.capture)).thenReturn(Mockito.mock(User.class));
3  
4 assertEquals("Yanbin", argumentCaptor.getValue().name);

 不能以这种方式在打桩的时候捕获参数:

1 when(userDao.findUserLike(argumentCaptor.capture)).thenReturn(getUser(argumentCaptor.getValue()));

否则会报错:

出错位置在打桩的地方。记住打桩并不等于异步调用,它返回的是个固定值!

转载于:https://www.cnblogs.com/fnlingnzb-learner/p/10595138.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/351075.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

以SYSTEM用户运行CMD

在SCCM 经常会以NT AUTHOR\SYSTEM帐户操作。 安以下步骤可以以SYSTEM帐户打开一个CMD窗口。 1. 从微软网站下载PSTool。 2. 以管理员运行CMD&#xff0c;进入到解压的PSTool目录。 3. 运行psexec -i -s cmd.exe 4. 在新打开的CMD中运行whoami。 注&#xff1a;这个指令可以让你…

matlab cell

如果p为一个数&#xff0c;那么h(1)p,是没有问题的。 如果p为一个向量&#xff0c;那么h(1,:)p是没有问题的。 如果p是一个矩阵的话&#xff0c;上面的两种赋值方法都是会有错误的。 那么要如何处理呢&#xff1f; 这时就用到了cell数据类型了。cell的每个单元都可以存储任何数…

jboss 不适用内置日志_适用于孩子,父母和祖父母的JBoss HornetQ –第1章

jboss 不适用内置日志现在与HornetQ合作已经快4年了&#xff0c;我认为现在该分享我到目前为止所学的部分知识了。 这篇文章的主要目的不是重写官方文档 &#xff0c;而是以简单的方式阐明我们在PaddyPower中最常用的概念。 什么是HornetQ HornetQ是JMS实现。 JMS是一种面向…

Spring Cloud微服务笔记(四)客户端负载均衡:Spring Cloud Ribbon

客户端负载均衡&#xff1a;Spring Cloud Ribbon 一、负载均衡概念 负载均衡在系统架构中是一个非常重要&#xff0c;并且是不得不去实施的内容。因为负载均衡对系统的高可用性、 网络压力的缓解和处理能力的扩容的重要手段之一。通常所说的负载均衡指的是服务端负载均衡&#…

matlab cell,fix,floor,round取整的几种方式

ceil函数的作用是朝正无穷方向取整&#xff0c;即将m/n的结果向正无穷方向取整&#xff0c;如m/n3.12&#xff0c;则ceil(m/n)的结果为4。 类似的函数有如下几个&#xff1a; fix&#xff1a;朝零方向取整&#xff0c;如fix(-1.3)-1;fix(1.3)1; floor&#xff1a;朝负无穷方…

孤儿进程与僵尸进程[总结]

1、前言 之前在看《unix环境高级编程》第八章进程时候&#xff0c;提到孤儿进程和僵尸进程&#xff0c;一直对这两个概念比较模糊。今天被人问到什么是孤儿进程和僵尸进程&#xff0c;会带来什么问题&#xff0c;怎么解决&#xff0c;我只停留在概念上面&#xff0c;没有深入&a…

使用CloudForms实现云运营幸福感的3个步骤

本周宣布&#xff0c; Cloud Suite管理层的最新功能 CloudForms 4.2可供所有人使用。 产品增加了1800多种改进&#xff0c;令许多令人兴奋的新奇事物令人兴奋。 CloudForms是Cloud Suite产品的Cloud Management平台&#xff0c;使您能够跨区域联合部署它以进行集中管理操作&am…

leetcode 599. 两个列表的最小索引总和(Minimum Index Sum of Two Lists)

目录 题目描述&#xff1a;示例 1:示例 2:解法&#xff1a;题目描述&#xff1a; 假设Andy和Doris想在晚餐时选择一家餐厅&#xff0c;并且他们都有一个表示最喜爱餐厅的列表&#xff0c;每个餐厅的名字用字符串表示。 你需要帮助他们用最少的索引和找出他们共同喜爱的餐厅。 如…

FAR,FRR,EER

FRR与FARFRR&#xff08;False Rejection Rate&#xff09;和FAR&#xff08;False Acceptance Rate&#xff09;是用来评估指纹识别算法性能的两个主要参数。FRR和FAR有时被用来评价一个指纹识别系统的性能&#xff0c;其实这并不贴切。指纹识别系统的性能除了受指纹算法的影响…

通过一段汇编,加深对寄存器ESP和EBP的理解

一直对寄存器ESP和EBP的概念总是有些混淆&#xff0c;查看定义ESP是栈顶指针&#xff0c;EBP是存取堆栈指针。还是不能很透彻理解。之后借于一段汇编代码&#xff0c;总算是对两者有个比较清晰的理解。下面是按调用约定__stdcall 调用函数test(int p1,int p2)的汇编代码;假设执…

Redis和数据库 数据同步问题

Redis和数据库同步问题缓存充当数据库比如说Session这种访问非常频繁的数据&#xff0c;就适合采用这种方案&#xff1b;当然了&#xff0c;既然没有涉及到数据库&#xff0c;那么也就不会存在一致性问题&#xff1b;缓存充当数据库热点缓存读操作目前的读操作有个固定的套路&a…

matlab fspecial创建滤波算子

Fspecial函数用于创建预定义的滤波算子&#xff0c;其语法格式为&#xff1a;h fspecial(type) h fspecial(type,parameters,sigma)参数type制定算子类型&#xff0c;parameters指定相应的参数&#xff0c;具体格式为&#xff1a;typeaverage&#xff0c;为均值滤波&#xff…

hibernate jpa_JPA / Hibernate:基于版本的乐观并发控制

hibernate jpa本文是对Hibernate和JPA中基于版本的乐观并发控制的介绍。 这个概念已经很老了&#xff0c;上面已经写了很多东西&#xff0c;但是无论如何我都看到了它被重新发明&#xff0c;误解和滥用。 我在写它只是为了传播知识&#xff0c;并希望引起对并发控制和锁定的兴趣…

X86汇编快速入门

本文翻译自&#xff1a;http://www.cs.virginia.edu/~evans/cs216/guides/x86.html 本文描述基本的32位X86汇编语言的一个子集&#xff0c;其中涉及汇编语言的最核心部分&#xff0c;包括寄存器结构&#xff0c;数据表示&#xff0c;基本的操作指令&#xff08;包括数据传送指令…

Django(三)框架之第二篇

https://www.cnblogs.com/haiyan123/p/7717788.html 一、知识点回顾 1、MTV模型 model&#xff1a;模型&#xff0c;和数据库相关的 template&#xff1a;模板&#xff0c;存放html文件&#xff0c;模板语法&#xff08;目的是将变量如何巧妙的嵌入到HTML页面中&#xff09;。 …

使用GDB调试C库

用gdb调试程序时&#xff0c;一般的函数都可以step进去&#xff0c;可是C库函数却直接跳过了。 网上找了些资料&#xff0c;记录一下&#xff01; 1.安装C库的debug版本 [plain] view plaincopy print?sudo apt-get install libc6-dbg 安装完后&#xff0c;在/usr/lib目录下…

matlab imfilter对图像进行滤波

功能&#xff1a;对任意类型数组或多维图像进行滤波。 用法&#xff1a;B imfilter(A,H)    B imfilter(A,H,option1,option2,...)    或写作g imfilter(f, w, filtering_mode, boundary_options, size_options) 其中&#xff0c;f为输入图像&#xff0c;w为滤波掩模&…

MapStruct:将数据从一个bean传输到另一个bean

将数据从一种形式转换为另一种形式在IT行业中是一种被高度利用的概念。 MapStruct通过在编译时生成映射器实现&#xff0c;允许基于注释的Bean转换。 这样可以确保在运行时没有性能开销。 什么是MapStruct&#xff1f; MapStruct是一个代码生成器&#xff0c;它基于约定优于配…

eclipse发布rest_在Eclipse中高效运行HTTP / REST集成测试

eclipse发布rest最近&#xff0c;我有机会使用由我亲爱的Holger Staudacher编写的OSGi-JAX-RS-Connector库。 通过连接器&#xff0c;您可以通过将Path注释的类型注册为OSGi服务来轻松发布资源-实际上&#xff0c;它工作得很好。 对我来说&#xff0c;使用普通的JUnit测试编写…

gdb调试命令

本文主要参考自&#xff1a;http://www.cnblogs.com/zzx1045917067/archive/2012/12/26/2834310.html&#xff0c;进行了一点补充和编排&#xff1b;Core dump部分参考了&#xff1a;http://blog.ddup.us/?p176。 gdb是一个在UNIX环境下的命令行调试工具。 如果需要使用gdb调试…