mockito入门_Mockito入门

mockito入门

本文是我们名为“ 用Mockito测试 ”的学院课程的一部分。

在本课程中,您将深入了解Mockito的魔力。 您将了解有关“模拟”,“间谍”和“部分模拟”的信息,以及它们相应的存根行为。 您还将看到使用测试双打和对象匹配器进行验证的过程。 最后,讨论了使用Mockito的测试驱动开发(TDD),以了解该库如何适合TDD的概念。 在这里查看 !

目录

1.为什么要模拟? 2. Mockito框架简介
2.1。 存根的快速示例 2.2。 快速验证示例
3.混合一个Mockito 4.将Mockito与JUnit一起使用 5. Mockito最佳做法

在本教程中,我们将研究Mockito Mocking Framework,并通过将其添加到类路径中来准备一个Eclipse项目来使用它。

1.为什么要模拟?

我们编写的所有代码都有一个相互依赖的网络,它可以调用其他几个类的方法,而这些类又可以调用其他方法。 确实,这就是面向对象编程的意图和力量。 通常在编写功能代码的同时,我们还将以自动化单元测试的形式编写测试代码。 我们使用这些单元测试来验证代码的行为,以确保其行为符合我们的预期。

当我们对代码进行单元测试时,我们希望对其进行隔离测试,并希望对其进行快速测试。 为了进行单元测试,我们只关心在当前测试的类中验证自己的代码。 通常,我们还希望非常定期地执行单元测试,重构时以及在持续集成环境中工作时,每小时可能要执行多次。

这是我们所有相互依存成为问题的时候。 我们可能最终在另一个类中执行代码,该类中的错误导致导致单元测试失败。 想象一下我们用来从数据库中读取用户详细信息的类,如果要运行单元测试时没有数据库,会发生什么? 想象一下,一个调用多个远程Web服务的类,如果它们出现故障或需要很长时间响应怎么办? 我们的单元测试可能由于我们的依赖关系而失败,而不是因为我们的代码行为出现问题。 这是不希望的。

除此之外,强制执行想要确保代码正确处理的特定事件或错误条件可能非常困难。 如果我们要测试某个反序列化对象的类如何正确处理可能的ObjectStreamException怎么办? 如果我们要测试协作者的所有边界返回值怎么办? 确保将某些计算值正确传递给协作者该怎么办? 如果可能的话,复制我们的测试条件可能需要花费大量的代码和较长的时间。

如果使用模拟,所有这些问题都会消失。 嘲笑就像是我们与之合作的类的替代品一样,它们取代了他们的位置,并按照我们告诉他们的行为去做。 嘲弄让我们假装我们真正的合作者在那里,即使他们不在。 更重要的是,可以对模拟程序进行编程,以返回我们想要的任何值并确认将任何值传递给它们。 模拟程序立即执行,不需要任何外部资源。 假人会返回我们告诉他们的东西,抛出我们想让他们抛出的任何异常,并将按需一遍又一遍地执行这些操作。 他们让我们仅测试我们自己代码的行为,以确保我们的类能够正常工作,而不管其协作者的行为如何。

有几种可用于Java的模拟框架,每种都有各自的语法,各自的优势,各自的劣势。 在本教程中,我们将使用Mockito框架,它是最流行的可用模拟框架之一。

2. Mockito框架简介

Mockito是一个Mocking框架,可以很容易地为要与您的被测类进行交互的类和接口创建模拟。 Mockito提供了一个非常简单的API,用于创建模拟并分配其行为。 它使您可以非常快速地指定预期的行为并验证与模拟的交互。

Mockito本质上具有两个阶段,其中一个或两个阶段都作为单元测试的一部分执行:

  • 存根
  • 验证

存根是指定模拟行为的过程。 这就是我们告诉Mockito与模拟互动时想要发生的事情的方式。 存根使我们能够解决我们在第一部分中概述的一些问题–它使为测试创建所有可能的条件变得简单。 它让我们控制了模拟的响应,包括强迫它们返回我们想要的任何值,或者抛出我们想要的任何异常。 它使我们可以在不同条件下编写不同的行为。 存根使我们可以精确控制模拟将执行的操作。

验证是验证与我们的模拟互动的过程。 它使我们能够确定模拟的调用方式以及调用的次数。 它使我们可以查看模拟的参数,以确保它们符合预期。 验证使我们能够解决第一节中提到的其他问题–它使我们确保将我们期望的值准确地传递给我们的合作者,并且不会发生意外情况。 验证使我们能够准确确定模拟发生了什么。

通过将这两个简单的阶段联系在一起,我们可以构建极其灵活且功能强大的单元测试,使用非常简单的Mockito API编码复杂的模拟行为和复杂的模拟交互验证。

Mockito确实有一些限制,包括

  • 你不能嘲笑期末班
  • 您不能模拟静态方法
  • 您不能模拟最终方法
  • 您不能模拟equals()或hashCode()

存根的快速示例

想象一下,您正在编写一个调用物理温度传感器API的类。 您要调用double getDegreesC()方法并基于从传感器返回的值返回以下字符串之一:“ Hot”,“ Mild”,“ Cold”。 至少可以说,要使单元测试控制房间的环境温度以测试功能非常困难。 但是,如果我们使用Mockito来创建替代传感器的模拟物,该怎么办?

现在我们可以在单元测试中编写如下代码:

when(sensor.getDegreesC()).thenReturn(15.0);

这告诉Mockito,当模拟传感器收到对getDegreesC()的调用时,它应该然后返回值15.0。

快速验证示例

假设您有一个类进行一些计算,并负责在观察者完成计算后通知观察者。 您想确保在执行方法的过程中一次调用了观察者的notify()方法。 您可以在观察器中设置一些布尔值,然后从单元测试中进行检查,但这意味着更改一些生产代码,甚至您可能都不拥有这些代码。 Mockito怎么样,如果观察者是模拟的呢?

现在我们可以在单元测试中编写如下代码:

verify(observer).notify();

这告诉Mockito必须仅一次调用一次notify()方法,否则单元测试应该失败。

3.混合一个Mockito

现在,我们已经了解了一些有关框架的知识,让我们在项目中使用它。

如果使用Maven,则将Mockito添加到项目中就像添加以下依赖项一样简单:

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId><version>1.9.5</version><scope>test</scope></dependency>

如果您使用Gradle,则只需添加以下内容

dependencies {testCompile "org.mockito:mockito-all:1.9.5"
}

要将旧版Mockito添加到Eclipse项目的类路径中,请从Mockito下载页面中获取最新的jar( 取名为 mockito-all-1.9.5.jar)并将其下载到硬盘上。

右键单击您的eclipse项目,然后选择“属性”,然后在左窗格中选择“ Java Build Path”,然后在右侧选择“ Libraries”。

在“库”选项卡上,单击“添加外部Jar”按钮,然后导航到您先前下载的模拟所有jar。 选择罐子,它现在已添加到您的项目中并可供使用。

在撰写本文时,Mockito的最新版本是1.9.5,但是在将其添加到项目之前,应检查更新。

4.将Mockito与JUnit一起使用

要将Mockito集成到您的JUnit测试类中,可以使用提供的Test Runner MockitoJUnitRunner 。 只需使用以下注释您的测试课:

@RunWith(MockitoJUnitRunner.class)

这告诉Mockito在测试类中接受所有带注释的模拟,并对其进行初始化以进行模拟。 然后,您可以简单地使用@Mock注释任何实例变量以将其用作模拟。 请注意,您应该导入org.mockito.Mock而不是org.mockito.mockitoannotations.Mock (已弃用)。

与所有示例一样,我们将创建一个新的Test类,并在其中使用Mockito模拟java.util.List

import java.util.List;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;@RunWith(MockitoJUnitRunner.class)
public class MyTest {@Mockprivate List<String> mockList;}

@Mock注释告诉Mockito模拟mockList将被视为模拟,而@RunWith(MockitoJUnitRunner.class)告诉Mockito遍历MyTest所有带有@Mock注释的成员,并将其初始化以进行模拟。 您不必将任何新实例分配给嘲笑列表,这是由Mockito在后台完成的。 通过上面的简单代码,mockList准备好用作模拟了。

尝试添加以下导入:

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import org.junit.Test;

然后是以下简单的测试用例:

@Testpublic void test() {String expected = "Hello, World!";when(mockList.get(0)).thenReturn(expected);String actual = mockList.get(0);assertEquals(expected, actual);System.out.println(actual);}

在这里,我们看到了我们的期望-我们有一个字符串"Hello, World!" 然后继续对模拟列表的List.get()方法进行存根, List.get()在请求列表的第一个元素时返回期望的String。

然后,我们调用mockList.get(0)以获取测试的实际值,并断言我们的实际值等于我们的预期值,然后将其输出到控制台以进行良好测量。

我们根本没有创建真实列表,也没有插入“ Hello,World!” 进入列表。 它只是一个模拟列表,它具有或知道的唯一功能是输入为0的get()方法。

尝试更改String actual = mockList.get(0);String actual = mockList.get(1); 并运行测试。 您将看到actual值现在为空。 原因是我们唯一保留的功能是使用输入0调用.get()– Mockito不知道如何使用输入1进行操作,因此它仅返回null。 实际上,我们调用List的任何其他方法都将返回null,而任何不返回任何值的方法将有效地充当no-op。 这是一个功能强大的控件,在几行代码中,我们创建了List的实现,该实现恰好在每次调用它时都可以实现我们想要的功能。

5. Mockito最佳做法

Mockito通常鼓励在单元测试和设计中采用标准的最佳实践,即:

  • Mockito没有模拟静态方法的规定,因为Mockito鼓励面向对象的设计和对过程代码的依赖注入。
  • Mockito没有提供模拟私有方法的规定,因为公共方法应该是黑盒,并且从测试私有方法的角度来看不存在。
  • Mockito打包并鼓励使用Hamcrest Matchers,这将在后续教程中介绍。
  • Mockito鼓励遵守Demeter法则,而不鼓励嘲笑链式方法。
  • 您不应存根或验证在不同线程之间共享的模拟。 但是,您可以调用共享模拟的方法。
  • 您无法验证模拟的toString()方法,原因是测试环境本身可能会调用它,因此无法进行验证。
  • 如果您的测试用例使用了“当时给定”表示法,则可以使用org.mockito.BDDMockito的存根方法,以便when(mock.method()).thenReturn(something)成为given(mock.method()).willReturn(something)因为它将以您的测试格式很好地阅读。
  • 可以在不使用Mockito批注的情况下使用Mockito,但是使用批注更加容易和整洁,这就是我们在这些教程中将要做的。
  • 如果您的测试要求您出于测试目的修改类的特定方法的行为,则可以“监视”任何类,包括被测类。 Mockito明确建议仅在偶尔使用间谍的情况下使用间谍,例如在处理遗留代码的情况下。 这将在以后的教程中介绍。
  • 如果对间谍方法的实际调用可能会产生错误条件,或者由于某些其他原因而无法调用,则Mockito建议使用do *系列方法进行存根。 这将在以后的教程中介绍。
  • Mockito将允许您使用参数匹配器代替实际参数,但有一个限制:如果一个参数使用匹配器,则所有参数都必须使用匹配器。 参数匹配器将在以后的教程中介绍,但应谨慎使用。
  • Mockito提供了verifyNoMoreInteractions()方法来验证特定的模拟没有更多的交互,但建议仅在适当的情况下谨慎使用。
  • Mockito提供了Answer接口以允许使用回调进行存根,但建议不要使用它,并鼓励您使用thenReturn()doThrow()方法进行简单的存根。 我们将在以后的教程中介绍答案。
  • 如果使用ArgumentCaptor进行参数验证,则应仅在验证阶段而不是存根阶段使用它。 ArgumentCaptor将在以后的教程中介绍。
  • Mockito建议非常小心地使用Partial Mocks,主要是在处理遗留代码时。 设计良好的代码不应要求使用部分模拟。
  • Mockito提供了一个reset()方法,用于在测试方法的中间重置模拟,但是建议您不要使用它,因为它是一种代码气味,可能会使您的测试过长且过于复杂。

有更多的功能和做法,但是这些是Mockito告诉您要注意的主要功能和做法。 我们将在接下来的教程中介绍以上所有内容,并进行更深入的介绍。

翻译自: https://www.javacodegeeks.com/2015/11/getting-started-with-mockito.html

mockito入门

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

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

相关文章

windows7安dns服务器_在Windows 7 上安装DNS服务器bind9方法详解

本文主要介绍在WIN7上利用ntbind部署DNS服务器的方法。ntbind是Bind的Windows版本&#xff0c;1.下载BIND9.11下载地址&#xff1a;http://ftp.isc.org/isc/bind9/9.11.0rc3/。我的系统是window 7 64位需要下载BIND9.11.0rc3.x64.zip&#xff0c;建议下载9.11以上的版本&#x…

腾讯大举退出美团!

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删11月16日&#xff0c;腾讯发布第三季度财报&#xff0c;同时表示将“分红式减持”美团。腾讯分派90.9%美团持股 腾讯系中概股美股盘前多数下跌腾…

csr8670 修改key_CSR8670 DFU user guide

DFU使用1)产生DFU keys&#xff1a;dfukeygenerate.exe -o keys或dfukeygenerate.exe -o keys -r random.txt生成keys.private.key和keys.public.key两个文件。2)loader和firmware签名&#xff1a;a)dfukeyinsert.exe -v -o loader_signed -lC:\ADK_CSR867x.WIN4.3.1.5\firmwar…

matchers依赖_Hamcrest Matchers教程

matchers依赖本文是我们名为“ 用Mockito测试 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入了解Mockito的魔力。 您将了解有关“模拟”&#xff0c;“间谍”和“部分模拟”的信息&#xff0c;以及它们相应的存根行为。 您还将看到使用测试双打和对象匹配器进行验证…

谷歌开源替代 C++ 的编程语言:Carbon

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删谷歌工程师 Chandler Carruth 近日在多伦多举办的 CppNorth 大会上宣布①&#xff0c;正式开源谷歌内部打造的编程语言&#xff1a;Carbon&#…

mediumtext和string转换_数据库用varchar和text的差别

数据库用varchar和text的差别发布时间&#xff1a;2018-05-09 20:41,浏览次数&#xff1a;1268, 标签&#xff1a;varchartext最近有几个同学问我varchar和text有啥别吗&#xff0c;这个问题&#xff0c;以前说真的也没太多的整理&#xff0c;以前遇到text在设计中就是尽可能的…

eai app_EAI的Spring集成教程

eai app课程大纲 Spring Integration是用于企业应用程序集成的开源框架。 这是一个轻量级的框架&#xff0c;建立在核心Spring框架之上。 它旨在支持开发事件驱动的体系结构和以消息为中心的体系结构典型的集成解决方案。 Spring Integration扩展了Spring编程模型&#xff0c;…

C语言灵魂拷问:++i为何比i++执行效率高!有何区别?

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删背景相信很多人遇到过这样的问题&#xff1a;printf("%d,%d",i,i);也纠结过这个问题&#xff0c;到底答案是什么。确没有一个参考的资…

java代码防止sql注入_动态Java代码注入

java代码防止sql注入在本文中&#xff0c;我们将研究如何将Java代码动态加载到正在运行的jvm中。 该代码可能是全新的&#xff0c;或者我们可能想更改程序中某些现有代码的功能。 &#xff08;在开始之前&#xff0c;您可能想知道为什么到底有人会这样做。显而易见的示例是规则…

指标实现层级_企业如何构建核心指标系统,实现业务运营效率提升90%?

本文为帆软数据生产力大赛获奖案例&#xff0c;未经授权禁止转载。01企业简介西安怡康医药连锁有限责任公司成立于2001年&#xff0c;总部设在西安市大庆路副24号,是一家由零售连锁药店发展起来的大型医药连锁企业&#xff0c;除药品零售外&#xff0c;同时兼营药品批发与器械批…

学生时代,你有遇到过像我这样理解C语言的吗?

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删今天我讲一下我个人对C语言的认识以及自己的理解&#xff0c;若有错误&#xff0c;还望指出&#xff0c;不甚感激。首先是C语言整体的脉络&#…

scrapyd部署_第八章 第一节 scrapyd和scrapy-client

如果觉得文章对您产生帮助的话, 欢迎关注Python开发之路(微信公众号: python-developer), 及时获取更多教程假设有我们做了一个项目是抓取很多网站(每个网站对应一个爬虫), 需要分别部署到不同的服务器上(单台扛不住), scrapy官方也提供了一种部署工具scrapyd。这个工具是用来将…

apache lucene_Apache Lucene基础教程

apache lucene课程大纲 Apache Lucene是一个免费/开源信息检索软件库&#xff0c;它提供基于Java的索引和搜索技术&#xff0c;以及拼写检查&#xff0c;命中突出显示和高级分析/令牌化功能。 Lucene是完全用Java编写的高性能&#xff0c;功能齐全的文本搜索引擎库。 它是一项…

C++ 首超 Java,与 Python、C语言共角逐年度最佳编程语言奖!

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删最新的 TIOBE 12 月编程语言已发布&#xff0c;先来预测一波今年的年度编程语言大奖究竟会花落谁家吧&#xff1f;C 首超 Java和上个月相比&…

matchers依赖_定制Hamcrest Matchers

matchers依赖本文是我们名为“ 用Mockito测试 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入了解Mockito的魔力。 您将了解有关“模拟”&#xff0c;“间谍”和“部分模拟”的信息&#xff0c;以及它们相应的存根行为。 您还将看到使用测试双打和对象匹配器进行验证…

乔安监控云存储能存多长时间_干货 | 监控磁盘阵列知识介绍,不了解还不来看看?...

一、磁盘阵列的概念要定义磁盘阵列的概念&#xff0c;是一个简单的工作&#xff0c;因为这个概念已经形成了共识——磁盘阵列(DiskArray)是由一个硬盘控制器来控制多个硬盘的相互连接&#xff0c;使多个硬盘的读写同步&#xff0c;减少错误&#xff0c;增加效率和可靠度的技术。…

我要是在学习 C 语言之前知道这些就好了!

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删对于我来说&#xff0c;学习 C 语言好难啊。这门语言本身的基础知识并不是很难&#xff0c;但是“用 C 语言编程”需要用到各种知识&#xff0c;…

opencv yuv保存本地_OpenCV-dlib-python3实现人脸戴墨镜和含Y的抖音效果

1 说明&#xff1a;1.1 吸烟有害健康&#xff01;&#xff01;纯属娱乐和学习python的相关知识。1.2 虽然是娱乐&#xff0c;但是opencv、dlib和python在人工智能、人脸识别、自动化等有很大作用&#xff0c;目前已经或者未来会有更多的应用&#xff0c;作为一名普通人&#xf…

lucene_Lucene组件概述

lucene本文是我们名为“ Apache Lucene基础知识 ”的学院课程的一部分。 在本课程中&#xff0c;您将了解Lucene。 您将了解为什么这样的库很重要&#xff0c;然后了解Lucene中搜索的工作方式。 此外&#xff0c;您将学习如何将Lucene Search集成到您自己的应用程序中&#xf…

为什么永远不会有语言取代 C/C++?

关注星标&#xff0c;每天学习C语言新技能因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源&#xff1a;网络数以百计的 C/C 替代品将会出现&#xff0c;但 C/C 将永远与我们同在&#xff01;每个 CPU 都带有一种称为 ISA&#xff08;指…