使用Mockito的Mock Void方法

大家好! 在我们之前的博客关于thenReturn和thenAnswer模拟方法之间的区别之后 ,我们又回来了关于Mockito的另一个有趣的博客。 在这里,我们将讨论“如何用Mockito模拟无效方法”。 让我们开始吧!

在编写代码时,总是至少有一种方法返回“ void”,并且在某个时间点需要模拟“ void”方法。 那么我们如何去做呢? 让我们在下面的博客中使用Mockito一起解决这个问题。

Mockito是用于编写单元测试的最著名的模拟框架之一。 如果您不喜欢模拟,可以在模拟网站上了解更多。

为什么我们需要模拟void方法?

假设我们有一个方法。 在此方法中,我们称为另一个void方法。 现在,当您要为该方法编写测试用例时,我们如何测试void方法被调用? 另外,是否将正确的参数传递给void方法?
在这种情况下,mockito可以帮助我们。

让我们举个例子,我们有一个UserService类。 在此类中,我们有一个updateName()方法。

 public UserService{ ... public void updateName(Long id, String name){ userRepository.updateName(id, name); }  } 

现在,我们要为UserService类编写单元测试并模拟userRepository。
但是,在此测试用例中,我们唯一需要验证的是使用正确的参数集调用了userRepository中的updateName()方法。
为此,我们需要模拟updateName()方法,捕获参数并验证参数。

这里要注意的最重要的一点之一是,我们不能仅仅使用Mockito的when-then机制来模拟void方法。 因为,mockito的when()方法适用于返回值,而方法无效时则不适用。

如何在Mockito中模拟void方法?

在Mockito中,我们可以使用不同的方法来调用实数方法或模拟void方法。 我们可以根据要求使用其中一个选项

  1. doNothing() :完全忽略对void方法的调用,这是默认行为
  2. doAnswer() :在调用void方法时执行一些运行时或复杂的操作
  3. doThrow()调用模拟的 void方法时引发异常
  4. doCallRealMethod() :不要模拟并调用真实方法

1)使用doNothing()

如果我们只想完全忽略void方法调用,则可以使用doNothing()。

在模拟中,对于模拟对象的每种方法,doNothing是默认行为。 因此,如果您不想验证参数,则使用doNothing是完全可选的。 在所有代码执行类似的行为之后,

将doNothing()用于void方法的示例

 @Test  public void testUpdateNameWithDoNothingVerifyRepositoryCall() { doNothing().when(mockedUserRepository).updateName(anyLong(),anyString()); userService.updateName(1L, "void mock test" );     verify(mockedUserRepository, times(1)).updateName(1L, "void mock test" );  } 

不对空方法使用doNothing()

 @Test  public void testUpdateNameWithOutDoNothingVerifyRepositoryCall() { userService.updateName(1L, "void mock test" );     verify(mockedUserRepository, times(1)).updateName(1L, "void mock test" );  } 

使用doNothing()进行参数捕获的示例

我们可以使用参数捕获来做不同的事情。 在这里,我们将只验证捕获的值

 @Test  public void testUpdateNameUsingArgumentCaptor() { ArgumentCaptor<Long> idCapture = ArgumentCaptor.forClass(Long. class ); ArgumentCaptor<String> nameCapture = ArgumentCaptor.forClass(String. class ); doNothing().when(mockedUserRepository).updateName(idCapture.capture(),nameCapture.capture());  userService.updateName(1L, "void mock test" );     assertEquals(1L, idCapture.getValue()); assertEquals( "void mock test" , nameCapture.getValue());  } 

2)将doAnswer()用于void方法

如果我们不想调用真实方法,则需要执行一些运行时操作,请使用doAnswer。

让我们以doAnswer为例,使用doAnswer打印并验证参数

 @Test  public void testUpdateNameUsingDoAnswer() { doAnswer(invocation -> { long id = invocation.getArgument(0); String name = invocation.getArgument(1); System.out.println( "called for id: " +id+ " and name: " +name); assertEquals(1L, id); assertEquals( "void mock test" , name); return null;  }).when(mockedUserRepository).updateName(anyLong(),anyString()); userService.updateName(1L, "void mock test" ); verify(mockedUserRepository, times(1)).updateName(1L, "void mock test" );  } 

3)使用doThrow()引发异常

如果要在调用方法时引发异常,则可以使用嘲笑的doThrow()方法。

让我们举一个例子,当使用null id调用updateName()方法时,我们将引发InvalidParamException。

 @Test(expected = InvalidParamException. class )  public void testUpdateNameThrowExceptionWhenIdNull() { doThrow( new InvalidParamException()) .when(mockedUserRepository).updateName(null,anyString(); userService.updateName(null, "void mock test" );  } 

4)使用doCallRealMethod()进行真实方法调用

有时有必要从模拟对象中调用真实方法,在这种情况下,我们需要使用doCallRealMethod(),因为doNothig()是默认行为。

在以下示例中,即使是模拟对象,也会调用userRepository中的真实方法。

 @Test  public void testUpdateNameCallRealRepositoryMethod() { doCallRealMethod().when(mockedUserRepository).updateName(anyLong(), anyString());  userService.updateName(1L, "calling real method" );  verify(mockedUserRepository, times(1)).add(1L, "calling real method" );  } 

快速阅读

  • 无效方法通常被模拟以检查是否使用正确的参数调用
  • 对于嘲笑void方法,当嘲笑机制无法工作时,因为它需要返回值
  • 可以使用doNothing(),doAnswer(),doThrow()或doCallRealMethod()处理无效方法
  • doNothing() :完全忽略void方法
  • doAnswer() :执行一些运行时或复杂的操作
  • doThrow() : 调用模拟的 void方法时引发异常
  • doCallRealMethod() :不要模拟并调用真实方法
  • 对于模拟对象,noNothing是每种方法的默认行为

翻译自: https://www.javacodegeeks.com/2020/06/mock-void-method-with-mockito.html

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

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

相关文章

System.gc()调用 - 适用的场景

一、System.gc()调用 System.gc()用于调用垃圾收集器&#xff0c;在调用时&#xff0c;垃圾收集器将运行以回收未使用的内存空间。它将尝试释放被丢弃对象占用的内存。然而System.gc&#xff08;&#xff09;调用附带一个免责声明&#xff0c;无法保证对垃圾收集器的调用。我们…

将模板方法模式应用到kmeans聚类算法

【0】README 0.1&#xff09;本文描述和源代码均为原创&#xff0c;旨在说明 如何将模板方法模式应用到kmean聚类算法&#xff1b; 0.2&#xff09;模板方法模式的intro&#xff0c; 参见 模板方法模式 0.3&#xff09;for kmeans alg source code, please visit kmeans&a…

java oca_OCA第4部分中的Java难题

java oca在Java Puzzlers的第四部分中&#xff0c;我们有一些与char类型有关的东西。 public class Puzzler { public static void main(String[] args){ char myChar a ; myChar; System.out.println(myChar); } } 您可能已经猜到了。 它将打印“ b”&#xff0c;其原因是c…

毕业设计的十大问题

一、vue的跨域问题 1、前端本地用代理软件代理服务器 在vue项目下的 config/index.js 文件里面配置代理proxyTable:proxyTable: {/login: {target: http://192.168.1.1:8080/ntd/data,changeOrigin: true,pathRewrite: {^/login:}}2、后台服务器开启允许跨域的响应头 直接在tom…

设计模式入门(策略模式)

【0】README0.1&#xff09;本文部分文字描述转自 “head first 设计模式”&#xff0c;旨在学习 设计模式入门&#xff08;策略模式&#xff09; 的基础知识&#xff1b;0.2&#xff09;本文章节4和5的source code&#xff0c;参见 设计模式——策略模式源代码【1】看个荔枝&a…

java oca_OCA的Java拼图游戏第3部分

java oca在Java难题的第三部分中&#xff0c;我们将看到变量命名限制方面的惊喜。 如果我向您展示了这一点&#xff0c;那么我相信您不会因为它无法编译而感到惊讶。 静态是保留关键字之一&#xff0c;为什么它应该起作用&#xff1f; public class Puzzler {public static v…

maven安装遇到的坑

一、环境变量设置没有反应 cmd窗口的设置未更新&#xff0c;需重新开启cmd窗口 二、缺失包 默认加载maven的仓库 配置minor导致官方的Maven库下载不了

单件模式(单例模式)

【0】README0.1&#xff09;本文部分描述转自 “head first 设计模式”&#xff0c; 旨在学习 单件模式&#xff08;单例模式&#xff09; 的相关知识 及其应用&#xff1b;【1】单件模式1.0&#xff09;单件模式的应用背景&#xff1a;有一些对象其实我们只需要一个&#xff0…

java oca_OCA第5部分中的Java难题

java oca在Java Puzzlers系列的第五部分中&#xff0c;我们将看到与X.parseX&#xff08;String s&#xff09;方法相关的内容。 您可以看到我们对X.parseX&#xff08;&#xff09;方法的期望。 public class Puzzler { public static void main(String[] args){ int i Inte…

Java Excel导出

一、Excel依赖包POI &#xff08;1&#xff09;Maven配置<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.7</version></dependency> &#xff08;2&#xff09;jar下载地址http://poi…

junit4和junit5_JUnit5 TestSuite替代

junit4和junit5JUnit4具有TestSuite类来聚合多个测试。 这在JUnit 5中不可用。通常&#xff0c;通过套件中的一堆命名测试进行的测试发现有些糟透了。 但是&#xff0c;如果目标不是测试发现&#xff0c;而是不同测试类之间的资源共享&#xff0c;那么创建一个父对象是有意义的…

Redis入门(一)之安装

一、下载Redis &#xff08;1&#xff09;Window 下载地址&#xff1a;https://github.com/MSOpenTech/redis/releases &#xff08;2&#xff09;Linux 下载地址&#xff1a;http://redis.io/download 二、安装Redis &#xff08;1&#xff09;window版本 A.解压Redis的zi…

mockito参数匹配_Mockito匹配器优先

mockito参数匹配这篇文章是意见。 让我们看一下Mockito中用于在Java中进行测试的verify方法。 示例&#xff1a; verify(myMock).someFunction(123) –期望在模拟ONCE上使用输入123调用someFunction 。 BDDMockito &#xff0c;我更喜欢完整的BDDMockito替代方案&#xff0c…

Redis入门(二)之数据类型

一、Redis 数据类型 Redis支持五种数据类型&#xff1a; &#xff08;1&#xff09;string&#xff08;字符串&#xff09; &#xff08;2&#xff09;hash&#xff08;哈希&#xff09; &#xff08;3&#xff09;list&#xff08;列表&#xff09; &#xff08;4&#x…

关于Object.clone克隆方法的测试

【0】README 0.1&#xff09;本文旨在用源代码测试说明&#xff0c; Object.clone 的 的克隆机制&#xff08;深拷贝 还是 浅拷贝&#xff09; 的问题&#xff1b; 0.2&#xff09;本文还添加了对System.arraycopy本地方法的测试&#xff08;干货——推荐使用该方法进行数组复…

超音速 启动_超音速亚原子图

超音速 启动MicroProfile GraphQL现在包含在刚发布的Quarkus 1.5.0版本中。 现在&#xff0c;您可以使用code.quarkus.io开始使用Quarkus&#xff0c;并包括SmallRye GraphQL Extension 。 这将创建一个具有以下依赖关系的Quarkus启动器应用程序&#xff1a; <dependency…

Java Json解析

一、Json &#xff08;1&#xff09;语法a.名称/值对数据表示b.大括号持有的对象和每个名称后跟“&#xff1a;”&#xff08;冒号&#xff09;&#xff0c;名称/值对的分离&#xff0c;&#xff08;逗号&#xff09;。c.方括号持有数组和值&#xff0c;&#xff08;逗号&#…

flink 卡夫卡_卡夫卡–一次语义学

flink 卡夫卡在分布式环境中&#xff0c;故障是很常见的情况&#xff0c;可以随时发生。 在Kafka环境中&#xff0c;代理可能崩溃&#xff0c;网络故障&#xff0c;处理故障&#xff0c;发布消息时失败或无法使用消息等。这些不同的场景引入了不同类型的数据丢失和重复。 失败…

Word中标题、图表自动编号的方法

转自&#xff1a;http://blog.sciencenet.cn/blog-344887-543229.html一般情况下&#xff0c;Word文档需要为标题提供连续编号&#xff0c;默认的标题样式并没有自动编号的功能&#xff0c;系统默认的标题样式效果如下图&#xff1a;正确设置标题自动编号的方法具体步骤如下&am…

java jsp总结

一、jsp简介 JSP&#xff08;全称Java Server Pages&#xff09;是由 Sun Microsystems 公司倡导和许多公司参与共同创建的一种使软件开发者可以响应客户端请求&#xff0c;而动态生成 HTML、XML 或其他格式文档的Web网页的技术标准。 JSP 技术是以 Java 语言作为脚本语言的&am…