过滤器匹配符包含单词

与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中的博客文章Moving Beyond Core 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仅包含一个String,因此使用contains匹配项进行测试的String的顺序和数量匹配。

如果订单匹配,则使用具有相同数量元素的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

过滤器匹配符包含单词

过滤器匹配符包含单词_Hamcrest包含匹配器相关推荐

  1. 【OpenCV-Python】——哈里斯/Shi-Tomas角检测FAST/SIFT/ORB特征点检测暴力/FLANN匹配器对象查找

    目录 前言: 1.角检测 1.1 哈里斯角检测 1.2 优化哈里斯角 1.3 Shi-Tomasi角检测 2.特征点检测 2.1 FAST特征点检测 2.2 SIFT特征检测 2.3 ORB特征检测 ...

  2. 正则匹配学习,示例:包含a和b,包含a不包含b,包含a不包含b和c

    正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串.将匹配的子串替换或者从某个串中取出符合某个条件的子串等. 构造正则表 ...

  3. java:单词接龙(dfs)(重点看看:包括相同单词不包含,还有找到第一个相同的开头单词相同的字母,连接字符串重复部分删除)

    java:单词接龙 题目 问题描述单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的"龙"(每个单词都最多在 ...

  4. django-DIL模板自定义过滤器,自定义标签,自定义包含标签

    django-DIL模板自定义过滤器,自定义标签,自定义包含标签 自定义过滤器 DTL模板语言生来只是为了方便的展示信息,所以与编程语言相比显得有点薄弱,有时候不能满足我们的需求.因此django提供 ...

  5. 正则表达式匹配:包含且不包含

    参考:http://www.jb51.net/article/52491.htm http://www.cnblogs.com/yirlin/archive/2006/04/12/373222.htm ...

  6. JS 使用正则匹配字符串中所有大括号包含的数据,转换成数组形式

    JS 使用正则匹配字符串中所有大括号包含的数据,转换成数组形式 .match(/{[^}{]*?}/g)

  7. python正则表达式匹配包含或者不包含字符串的方法

    记录下正则匹配包含或者不包含字符串的表达式 import time import refindStr = 'setAttr ".uvst[0].uvsn" -type " ...

  8. spaCy V3.0 基于规则匹配(2)----高效的短语匹配器和依存句法匹配器

    1 短语匹配器(PhraseMatcher) 1.1 基本用法 对于需要匹配大型术语列表的情况,可以通过PhraseMatcher和创建Doc对象来代替词符匹配模式(token patterns),可 ...

  9. QL Server 中四种匹配符的含义

    SQL中我们会见到很多的匹配符,下面解释一下 % 代表零个或者多个任意字符_ 代表一个任意字符[] 指定范围内的任意单个字符[^] 不在指定范围内的任意单个字符带有匹配符的字符串必须使用引号引起来,例 ...

最新文章

  1. Laravel中Redis的配置和使用
  2. [学习笔记]python
  3. Shell(9)——sed(1)
  4. kafka异步发送数据_在Kafka上异步发送数据
  5. SQL Server存储过程基本语法
  6. AD18的安装教程(包括资料)
  7. 报 刊 集 锦(转载)
  8. CISSP工资百万, 认证培训2899美元,是不是太高?
  9. 重启linux系统后 启动mysql ERROR! The server quit without updating PID file /var/run/mysqld/mysqld.pid
  10. ASP.NET 安全认证(二)——灵活运用 Form 表单认证中的 deny 与 allow 及保护 .htm 等文件(转)...
  11. DataType--类型基础
  12. iOS项目中用到的一些第三方库
  13. [转帖]LCD与LED的区别之背光原理与优缺点对比介绍
  14. day61——自我检讨
  15. AV1 motion filed projection
  16. 指标管理是如何优化目标管理体系的!
  17. yarn Integrity check failed ... computed integrity doesn‘t match our records
  18. background-size:cover与-webkit-background-size
  19. python实现批量修改图片尺寸和图片名称
  20. VBS基础篇 - 循环语句(2) - While...Wend

热门文章

  1. Java 程序员必须掌握的 5 个注解
  2. 为什么说Java中只有值传递(另一种角度)
  3. 阿里巴巴对Java编程【应用结构】的规约
  4. python打包exe文件
  5. 学会它,可以替你写100行 200行 300行……的代码
  6. 《白鹿原》金句摘抄(二)
  7. java 单例 生命周期_单例模式--- 声明周期托管方式
  8. php制作留言板的题_PHP实现留言板功能实例代码
  9. python scratch unity_Unity3D研究院之2D游戏开发制作原理(二十一)
  10. NanoHTTPD web server的一个简单荔枝