文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Mockito 一个优秀的 Mock 测试框架

2024-12-03 04:10

关注

本文转载自微信公众号「Java极客技术」,作者鸭血粉丝 。转载本文请联系Java极客技术公众号。

Hello 大家好,我是阿粉,日常工作中很多时候我们都需要同事间的相互配合协作完成某些功能,所以我们经常会遇到服务或者应用内不同模块之间要互相依赖的场景。比如下面的场景,serviceA 中的 methodA() 方式依赖 serviceB 中的 methodB() 方法返回操作的结果。那如果我们要对自己的methodA() 方法进行编写单元测试,还需要等其他同事的methodB() 方法开发完成才行。那有没有什么办法我们可以跳过或者说模拟方法 B 的输出呢?这就引出了我们今天的主角 Mockito,一个优秀的 Mock 测试框架。

我们通过使用 Mock 技术可以让开发不停滞,Mock技术的作用是将服务与服务之间的依赖在测试自测阶段隔离开,让开发人员在自己的应用内部通过模拟的方式把需要依赖外部的接口给构造出来,从而保证不被外界的开发进度所影响。今天我们要谈到的Mockito 就是一个优秀的 Mock 框架。

Mockito

Mockito is a mocking framework that tastes really good. It lets you write beautiful tests with a clean & simple API. Mockito doesn’t give you hangover because the tests are very readable and they produce clean verification errors.

Mockito 是一个很好用的模拟框架。它让您可以使用干净简单的 API 编写漂亮的测试。Mockito 的可读性非常好,不会让你感动迷惑,产生的验证错误也很明确。

官网地址:https://site.mockito.org/

中文文档:https://github.com/hehonghui/mockito-doc-zh#0

测试用例 1

首先在工程的 pom 文件里面加依赖,我们加上 mockito 和junit 的依赖。

  1.  
  2.   org.mockito 
  3.   mockito-all 
  4.   1.9.5 
  5.   test 
  6.  
  7.  
  8.  
  9.   junit 
  10.   junit 
  11.   4.11 
  12.   test 
  13.  

接下来我们编写一个简单的测试用例,这里我们通过mock 一个 List 对象,先添加几个元素,后面验证添加交互是否与我们预期的一致。

  1. @Test 
  2. public void testVerify() throws Exception { 
  3.   //创建 mock 对象 
  4.   List mockedList = mock(List.class); 
  5.   mockedList.add("test1"); 
  6.   mockedList.add("test2"); 
  7.   mockedList.add("test2"); 
  8.   mockedList.clear(); 
  9.   //验证是否执行了一次 add("test1") 操作 
  10.   verify(mockedList).add("test1"); 
  11.   //同上面验证是否执行了一次 add("test1") 操作,默认就是 time(1) 
  12.   verify(mockedList, times(1)).add("test1"); 
  13.   //验证是否执行了3次 add("test2") 操作 
  14.   //verify(mockedList, times(3)).add("test2"); 
  15.   verify(mockedList).clear(); 

上面的测试用例我们运行过后是如下效果,测试用例是通过的。

当我们放开verify(mockedList, times(3)).add("test2"); 这一行代码进行运行时,我们可以看到测试用例未通过,提示的错误是我们预期执行 3 次,结果实际只执行了 2 次add("test2") 操作。

上面的测试用例是验证对应方式的执行次数是否和预期一致,除了有准确的次数之外,还有最多,至少,从未等验证方式,如下所示:

  1. //精确次数 
  2.  verify(mockedList, times(3)).add("test2"); 
  3.  //至少 1次 
  4.  verify(mockedList, atLeastOnce()).add("test2"); 
  5.  //至少 2 次 
  6.  verify(mockedList, atLeast(2)).add("test2"); 
  7.  //最多 5 次 
  8.  verify(mockedList, atMost(5)).add("test2"); 

测试用例 2

通过设值或者打桩的方式预设参数,如下所示,当执行 get(0) 操作时,我们通过 thenReturn()方法返回 hello,当执行 get(1)操作时我们抛出空指针异常,运行结果如下图所示:

  1. @Test 
  2. public void testWhen() throws Exception { 
  3.   LinkedList mockedList = mock(LinkedList.class); 
  4.   //设置值,通常被称为打桩 
  5.   when(mockedList.get(0)).thenReturn("hello"); 
  6.   when(mockedList.get(1)).thenThrow(new NullPointerException()); 
  7.   System.out.println(mockedList.get(0)); 
  8.   //这里会打印 "null" 因为 get(2) 没有设置 
  9.   System.out.println(mockedList.get(2)); 
  10.   //这里会抛 exception 
  11.   System.out.println(mockedList.get(1)); 
  12.   //验证有没有执行 get(0) 操作 
  13.   verify(mockedList).get(0); 

可以看到当我们调用 get(0) 和 get(1) 的时候控制台成功的抛出了异常。这种方式通常被称为Stubbing,除了使用 when...thenReturn 方式之外,还有一种形式可以表达,代码如下:

  1. @Test 
  2. public void testDoReturn() throws Exception { 
  3.   Iterator mockedList = mock(Iterator.class); 
  4.   doReturn("hello").when(mockedList).next(); 
  5.   Object next = mockedList.next(); 
  6.   System.out.println(next); 
  7.   doReturn("world").when(mockedList).next(); 
  8.   Object next2 = mockedList.next(); 
  9.   System.out.println(next2); 
  10.   //上面的过程也可以写成如下方式 
  11.   doReturn("test1""test2").when(mockedList).next(); 
  12.   Object next3 = mockedList.next(); 
  13.   System.out.println(next3); 
  14.   Object next4 = mockedList.next(); 
  15.   System.out.println(next4); 

运行结果如下所示,也可以用 doThrow() 方法进行抛异常:

测试用例 3

日常开发中我们通过要保证方法的时效性,或者说我们要保证我们某个方法必须在多长时间内执行完成,这个时候我们也可以通过 mock 的方式来验证我们的方法是否满足要求。代码如下:

  1. @Test 
  2. public void testTimeout() throws Exception { 
  3.       HttpService mock = mock(HttpService.class); 
  4.       String url = "http://www.xxx.com"
  5.       mock.getRequest(url); 
  6.       verify(mock, timeout(100)).getRequest(url); 
  7.       //timeout时间后,用自定义的检验模式验证getRequest() 
  8.       VerificationMode customVer = new VerificationMode() { 
  9.         @Override 
  10.         public void verify(VerificationData data) { 
  11.  
  12.         } 
  13.  
  14.         @Override 
  15.         public VerificationMode description(String s) { 
  16.           return null
  17.         } 
  18.       }; 
  19.       verify(mock, new Timeout(100, customVer)).getRequest(url); 

Mockito 还有很多 API 可以使用,更多的使用方式,大家可以参考这面这个网站。https://www.tutorialspoint.com/mockito/mockito_timeouts.htm,有更详细的介绍。

 

来源:Java极客技术内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯