Hamcrest包含匹配器

与Hamcrest 1.2相比 ,针对Matchers类的Hamcrest 1.3 Javadoc文档为该类的几种方法添加了更多文档。 例如,四个重载的contains方法具有更具描述性的Javadoc文档,如下面所示的两个比较屏幕快照所示。

尽管仅通过尝试就可以弄清楚“包含”匹配器的工作方式,但是Hamcrest 1.3中的Javadoc使得阅读它们的工作方式更加容易。 大多数Java开发人员在考虑contains()方法时,可能会想到类似String.contains(CharSequence)或Collection.contains(Object)的行为。 换句话说,大多数Java开发人员可能将“包含”描述为描述String / Collection是否包含提供的字符/对象以及其他可能的字符/对象。 但是,对于Hamcrest匹配器,“包含”具有更具体的含义。 随着Hamcrest 1.3文档更加清晰明了,“包含”匹配项对传递给这些方法的项目数量和项目顺序更加敏感。

此处显示的示例使用JUnit和Hamcrest。 这里要强调的是,Hamcrest的JAR文件必须在JUnit的JAR文件之前出现在单元测试的类路径中,否则我必须使用为与独立的Hamcrest JAR一起使用而构建的“特殊” JUnit JAR文件。 使用这些方法之一可以避免NoSuchMethodError和其他错误(例如org.hamcrest.Matcher.describeMismatch错误),这是由类的版本不匹配导致的。 我已经在JUnit的博客超越核心Hamcrest中撰写了有关JUnit / Hamcrest细微差别的文章。

接下来的两个屏幕快照指示了单元测试代码段的结果(如NetBeans 7.3所示),我将在稍后的博客中展示这些单元测试代码段,以演示包含匹配器的Hamcrest。 这些测试应该有一些失败(7个测试通过,4个测试失败),以使Hamcrest匹配器在不阅读Javadoc的情况下可能无法按预期工作的地方很明显。 第一张图片仅显示5个测试通过,2个测试失败和4个测试导致错误。 这是因为在NetBeans项目的“测试库”类路径中,在Hamcrest之前列出了JUnit。 第二个图像显示了预期的结果,因为Hamcrest JAR发生在项目的“测试库”类路径中的JUnit JAR之前。

为了演示的目的,我有一个简单的人为设计的类要测试。 接下来显示该Main类的源代码。

Main.java

package dustin.examples;import java.util.Collections;
import java.util.HashSet;
import java.util.Set;/*** Main class to be unit tested.* * @author Dustin*/
public class Main
{/** Uses Java 7's diamond operator. */private Set<String> strings = new HashSet<>();public Main() {}public boolean addString(final String newString){return this.strings.add(newString);}public Set<String> getStrings(){return Collections.unmodifiableSet(this.strings);}
}

显示了要测试的类之后,现在该考虑使用Hamcrest匹配器构建一些基于JUnit的测试了。 具体来说,测试是为了确保通过类的addString(String)方法添加的addString(String)位于其基础Set并且可以通过getStrings()方法访问。 接下来显示的单元测试方法演示了如何适当地使用Hamcrest匹配器来确定类的基础Set是否包含添加的字符串。

在Set Works中将Hamcrest contains()匹配器与单个字符串一起使用

/*** This test will pass because there is only a single String and so it will* contain that single String and order will be correct by implication.*/@Testpublic void testAddStringAndGetStringsWithContainsForSingleStringSoWorks(){final Main subject = new Main();final boolean resultJava = subject.addString('Java');final Set<String> strings = subject.getStrings();assertThat(strings, contains('Java'));}

上面显示的单元测试通过了,因为Set仅包含一个字符串,因此使用contains匹配项进行测试的字符串的顺序和数量匹配。

如果订单匹配,则使用具有相同数量元素的Hamcrest容器有效

/*** The 'contains' matcher expects exact ordering, which really means it should* not be used in conjunction with {@code Set}s. Typically, either this method* will work and the method with same name and '2' on end will not work or* vice versa.*/@Testpublic void testAddStringAndGetStringsWithContainsForMultipleStringsNotWorks1(){final Main subject = new Main();final boolean resultJava = subject.addString('Java');final boolean resultGroovy = subject.addString('Groovy');final Set<String> strings = subject.getStrings();assertThat(strings, contains('Java', 'Groovy'));}/*** The 'contains' matcher expects exact ordering, which really means it should* not be used in conjunction with {@code Set}s. Typically, either this method* will work and the method with same name and '1' on end will not work or* vice versa.*/@Testpublic void testAddStringAndGetStringsWithContainsForMultipleStringsNotWorks2(){final Main subject = new Main();final boolean resultJava = subject.addString('Java');final boolean resultGroovy = subject.addString('Groovy');final Set<String> strings = subject.getStrings();assertThat(strings, contains('Groovy', 'Java'));}

上面显示的两个示例单元测试以及运行这些测试的结果输出(如上一个屏幕快照所示)显示,只要contains()匹配器的参数数量与要测试的集合中的Strings数量相同, , 如果所测试的元素与集合中的元素完全相同的顺序,则匹配可能有效。 对于无序的Set ,不能依赖此顺序,因此contains()不太可能是与多个元素的Set上的单元测试一起使用的良好匹配器。

使用具有不同数量元素的Hamcrest容器永远行不通

/*** Demonstrate that contains will NOT pass when there is a different number* of elements asked about contains than in the collection.*/@Testpublic void testAddStringAndGetStringsWithContainsNotWorksDifferentNumberElements1(){final Main subject = new Main();final boolean resultJava = subject.addString('Java');final boolean resultGroovy = subject.addString('Groovy');final Set<String> strings = subject.getStrings();assertThat(strings, contains('Java'));}/*** Demonstrate that contains will NOT pass when there is a different number* of elements asked about contains than in the collection even when in* different order.*/@Testpublic void testAddStringAndGetStringsWithContainsNotWorksDifferentNumberElements2(){final Main subject = new Main();final boolean resultJava = subject.addString('Java');final boolean resultGroovy = subject.addString('Groovy');final Set<String> strings = subject.getStrings();assertThat(strings, contains('Groovy'));}

作为JUnit测试结果表明,这两个单元测试从未通过,因为在被测试元件的数目Set为比在元件的数量较少的Set 。 换句话说,这证明了contains()匹配器不会简单地测试集合中的给定元素:它会测试所有指定元素的存在和指定顺序。 在某些情况下,这可能太过局限了,所以现在我将继续进行Hamcrest提供的其他一些确定项,以确定特定集合中是否包含元素。

使用Hamcrest的containsInAnyOrder()匹配器

containsInAnyOrder匹配器不如contains()匹配器严格:它允许被测试的元素以任何顺序通过包含集合中的元素。

/*** Test of addString and getStrings methods of class Main using Hamcrest* matcher containsInAnyOrder.*/@Testpublic void testAddStringAndGetStringsWithContainsInAnyOrder(){final Main subject = new Main();final boolean resultJava = subject.addString('Java');final boolean resultCSharp = subject.addString('C#');final boolean resultGroovy = subject.addString('Groovy');final boolean resultScala = subject.addString('Scala');final boolean resultClojure = subject.addString('Clojure');final Set<String> strings = subject.getStrings();assertThat(strings, containsInAnyOrder('Java', 'C#', 'Groovy', 'Scala', 'Clojure'));}/*** Use containsInAnyOrder and show that order does not matter as long as* all entries provided are in the collection in some order.*/@Testpublic void testAddStringAndGetStringsWithContainsInAnyOrderAgain(){final Main subject = new Main();final boolean resultJava = subject.addString('Java');final boolean resultGroovy = subject.addString('Groovy');final Set<String> strings = subject.getStrings();assertThat(strings, containsInAnyOrder('Java', 'Groovy'));assertThat(strings, containsInAnyOrder('Groovy', 'Java'));}

上方显示的两个单元测试都通过了,尽管被测试的字符串以与两个集合中可能存在的顺序不同的顺序提供给containsInAnyOrder()匹配器。 但是,不太严格的containsInAnyOrder()匹配器仍要求将包含集合的所有元素指定为传递。 由于不满足此条件,因此以下单元测试未通过。

/*** This will fail because containsInAnyOrder requires all items to be matched* even if in different order. With only one element being tried and two* elements in the collection, it will still fail. In other words, order* does not matter with containsInAnyOrder, but all elements in the collection* still need to be passed to the containsInAnyOrder matcher, just not in the* exact same order.*/@Testpublic void testAddStringAndGetStringsWithContainsInAnyOrderDiffNumberElements(){final Main subject = new Main();final boolean resultJava = subject.addString('Java');final boolean resultGroovy = subject.addString('Groovy');final Set<String> strings = subject.getStrings();assertThat(strings, containsInAnyOrder('Java'));}

Hamcrest hasItem()和hasItems()匹配器像声音一样工作

如接下来的两个单元测试方法(均通过)所示,Hamcrest hasItem() (用于单个项目)和hasItems (用于多个项目)成功地测试了一个集合分别具有一个或多个指定项目,而无需考虑用于指定项目的订单或数量。 这实际上更像大多数Java开发人员在处理Strings和collections时“包含”工作。

/*** Demonstrate hasItem() will also work for determining a collection contains* a particular item.*/@Testpublic void testAddStringAndGetStringsWithHasItem(){final Main subject = new Main();final boolean resultJava = subject.addString('Java');final boolean resultGroovy = subject.addString('Groovy');final Set<String> strings = subject.getStrings();assertThat(strings, hasItem('Groovy'));assertThat(strings, hasItem('Java'));}/*** Demonstrate that hasItems works for determining that a collection has one* or more items and that the number of items and the order of the items* is not significant in determining pass/failure.*/@Testpublic void testAddStringAndGetStringsWithHasItems(){final Main subject = new Main();final boolean resultJava = subject.addString('Java');final boolean resultGroovy = subject.addString('Groovy');final Set<String> strings = subject.getStrings();assertThat(strings, hasItems('Groovy', 'Java'));assertThat(strings, hasItems('Java', 'Groovy'));assertThat(strings, hasItems('Groovy'));assertThat(strings, hasItems('Java'));}

Hamcrest isIn()匹配器从其他方向测试遏制

刚刚讨论过的hasItem()hasItems()匹配器不如contains()严格,甚至不如containsInAnyOrder()严格,并且经常是人们想要简单地确保一个或多个项目在集合中某处而又没有的情况下想要的关注该集合中的项目顺序或该集合中其他可能的项目。 使用Hamcrest确定相同关系的另一种方法是使用isIn匹配器,但从相反的角度来看。 isIn匹配器确定某个项目是否位于提供给匹配器的集合的某个位置,而无需考虑该项目在集合中的顺序,或者不考虑该集合中是否还有其他项目。

/*** Use isIn matcher to test individual element is in provided collection.*/@Testpublic void testAddStringAndGetStringsWithIsIn(){final Main subject = new Main();final boolean resultJava = subject.addString('Java');final boolean resultGroovy = subject.addString('Groovy');final Set<String> strings = subject.getStrings();assertThat('Groovy', isIn(strings));assertThat('Java', isIn(strings));}

结论

Hamcrest提供了一组丰富的匹配器,可用于确定指定的元素是否驻留在指定的集合中。 在决定应用这些和确定使用哪个时,请记住以下重要点:

  • 确保Hamcrest JAR在JUnit JAR之前位于测试类路径上。
  • 使用contains当你想确保集合包含了所有规定的项目,没有其他物品,你想收集包含指定顺序的项目。
    • 通常应避免对Set s使用contains()匹配器,因为它们本质上是无序的。
  • 当您仍要严格测试是否在测试中指定的集合中存在完全相同的项目时,请使用containsInAnyOrder匹配器,但不必关心顺序(适用于Set )。
  • 使用hasItem()hasItems()匹配器询问集合是否包含(可能在其他未列出的项目中,并且没有特定的顺序)指定的项目。
  • 使用isIn()匹配器询问特定项是否在指定的集合中,而与其他项是否在该集合中或该项在包含的集合中的顺序无关。

参考:来自我们的JCG合作伙伴 Dustin Marx的Hamcrest包含匹配器 ,位于Inspired by Actual Events博客上。

翻译自: https://www.javacodegeeks.com/2013/01/hamcrest-containing-matchers.html

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

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

相关文章

函数 (四) 迭代器和生成器

一 迭代器 一 迭代的概念 #迭代器即迭代的工具&#xff0c;那什么是迭代呢&#xff1f;#迭代是一个重复的过程&#xff0c;每次重复即一次迭代&#xff0c;并且每次迭代的结果都是下一次迭代的初始值 while True: #只是单纯地重复&#xff0c;因而不是迭代print(>) l[1,2,3]…

进阶-JMS 知识梳理

JMS 一、 概述与介绍 ActiveMQ 是Apache出品&#xff0c;最流行的、功能强大的即时通讯和集成模式的开源服务器。ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现。提供客户端支持跨语言和协议&#xff0c;带有易于在充分支持JMS 1.1和1.4使用J2EE企业集成模式…

android蓝牙pair,Android向更多蓝牙设备开放Fast Pair功能 配对更轻松了

原标题&#xff1a;Android向更多蓝牙设备开放Fast Pair功能 配对更轻松了 来源&#xff1a;cnBeta.COM蓝牙是一项应用非常广泛的无线技术&#xff0c;在无线音频配件、智能手表和智能家电中都广泛使用。不过蓝牙设备的配对体验并不优秀&#xff0c;而且无法实现跨平台的一致性…

python绘制帕累托图

python绘制帕累托图代码 1 import pandas as pd2 import matplotlib.pyplot as plt3 plt.rcParams[font.sans-serif][SimHei]#表示可以显示中文4 plt.rcParams[axes.unicode_minus]False#表示可以正常显示正负号5 datapd.read_csv(catering_dish_profit.csv,index_coltype)6 pr…

html5 测评游戏,暗黑之王评测:HTML5游戏铸就最华丽ARPG冒险

由白鹭时代(Egret Technology)与比悦科技联手推出的重度大型HTML5游戏《暗黑之王》&#xff0c;一款典型的ARPG手游&#xff0c;其HTML5版本推出以来&#xff0c;获得了来自业界、玩家和媒体的大量关注。其丰富的游戏内容和玩法&#xff0c;加上卓越的游戏性能表现&#xff0c;…

搞定flex布局

这几种方式的搭配使用可以轻松搞定 PC 端页面的常见需求&#xff0c;比如实现水平居中可以使用 margin: 0 auto&#xff0c;实现水平垂直同时居中可以如下设置&#xff1a;.dad {position: relative; } .son {position: absolute;margin: auto;top: 0;right: 0;bottom: 0;left…

Fiddler抓包使用教程-QuickExec

转载请标明出处&#xff1a;http://blog.csdn.net/zhaoyanjun6/article/details/73468287 本文出自【赵彦军的博客】 在 Fiddler 中自带了一个 QuickExec 命令行&#xff0c;用户可以直接输入并快速执行脚本命令。 常见命令 help 打开官方的使用页面介绍&#xff0c;所有的命令…

html5与css3都要学吗,前端要学css3吗?

前端要学css3&#xff1b;HTML5、CSS3是前端工程师必须要学会。现在移动端的兴起&#xff0c;导致web前端开发的技术逐变向css3和html5转变&#xff0c;所以css3一定要学。CSS3是CSS(层叠样式表)技术的升级版本&#xff0c;于1999年开始制订&#xff0c;2001年5月23日W3C完成了…

react 判断图片是否加载完成_React中型项目的优化实践

项目介绍整个项目大概有60个页面&#xff0c;用到的组件大概150&#xff0c;package里面的依赖大概有70个&#xff0c;应该勉强算得上是一个中型的React的项目了。下面给大家看看我们现在build一次项目的结果--打包时间约150s&#xff0c;打包完之后的资源gzip之后约1.2m&#…

搭建本地wordpress

1.首先&#xff0c;下载xampp&#xff0c;安装按默认勾选即可。 2.安装完成后&#xff0c;启动Apache和MySQL这两个服务。 启动后变成绿色&#xff0c;表示启动成功。 3.点击MySQL项的Admin进入数据库后台。 4.点击用户账户新建用户。 5.填写用户名&#xff0c;host name选本地…

Python基础【day02】:字符串(四)

在Python中字符串本身有带很多操作&#xff0c;字符串的特性&#xff0c;不可以被修改 0、字符串常用功能汇总 1、字符串的定义 #定义空字符串>>> name#定义非空字符串 >>> name"luoahong"#通过下标访问 >>> name[1] u#不能修改字符串的值…

html5 窗口变形,HTML5画布(变形)

坐标变换案例1&#xff1a;function draw(){var cdocument.getElementById("myCanvas");var cxt c.getContext("2d");cxt.translate(200,50);cxt.fillStylergba(255,0,0,0.25);for(var i0;i<40;i){cxt.translate(25,25);cxt.scale(0.9,0.9);cxt.rotate(…

appium GUI介绍

Appium作为APP端的自动化测试工具&#xff0c;具有很多的有点&#xff0c;今天主要介绍一下它的UI界面&#xff0c;包含其中的一些参数等。主要说的是windows下的APPIUM GUI。 先看一眼它的界面(版本为1.4.16.1) 注: 1.android Settings - Android设置按钮&#xff0c;所有和安…

迭代器模式和Java

大家好&#xff0c;在本文中&#xff0c;我们将检查Iterator Pattern 。 我知道你们中许多人已经使用过一种设计模式&#xff0c;但是也许您没有意识到它是模式&#xff0c;或者不知道它的巨大价值。 根据《 Head First Design 》一书&#xff1a; 迭代器模式提供了一种在不暴…

不使用JavaScript实现菜单的打开和关闭

我在写有菜单栏的网页时&#xff0c;基本都会用响应式设计来适配移动端&#xff0c;例如把不重要的菜单选项隐藏&#xff0c;或者创建一个菜单按钮来控制的菜单的打开和关闭之类的。而我之前一直是使用JavaScript来实现菜单的打开和关闭的&#xff0c;但最近在网上看到有人使用…

芝枝.计算机与人文科学,计算机与人文科学

计算机与人文科学(2013-03-13 13:24:17)标签&#xff1a;文化战争名著《静静的顿河》可以说从它诞生起便没有平静过&#xff0c;围绕它的作者所引起的争议&#xff0c;就像它获得诺贝尔文学奖一样&#xff0c;撼动文坛&#xff0c;有人指控肖洛霍夫是个骗子&#xff0c;《静静的…

HTML5 Canvas游戏开发实战 PDF扫描版

HTML5 Canvas游戏开发实战主要讲解使用HTML5 Canvas来开发和设计各类常见游戏的思路和技巧&#xff0c;在介绍HTML5 Canvas相关特性的同时&#xff0c;还通过游戏开发实例深入剖析了其内在原理&#xff0c;让读者不仅知其然&#xff0c;而且知其所以然。在本书中&#xff0c;除…

css3图片垂直居中

图片相对父元素垂直居中, css3属性给父级元素设置 display: -webkit-box; -moz-box-align: center; -webkit-box-align: center; -moz-box-pack: center; -webkit-box-pack: center; 需要注意的是&#xff1a; 父级元素要有确定的高度&#xff01;

网络局域网看不到其它计算机,局域网中看不到其它计算机怎么办

通过网上邻居或查看网络计算机时&#xff0c;看不到局域网中其它计算机&#xff0c;这是怎么回事呢?下面是学习啦小编给大家整理的一些有关看不到局域网中其它计算机的解决方法&#xff0c;希望对大家有帮助!局域网中看不到其它计算机的解决方法打开“控制面板”-“网络和Inte…

计算机二级高级应用考题,2016计算机二级MSOFFICE高级应用考试真题

2016计算机二级MSOFFICE高级应用考试真题离2016上半年的计算机等级考试只有一个多月了&#xff0c;为了帮助大家尽快考试过关&#xff0c;小编整理了计算机二级office考试题&#xff0c;希望能帮助到大家!(1)下列叙述中正确的是A)一个算法的空间复杂度大&#xff0c;则其时间复…