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.pswp.cn/news/370024.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/370024.shtml
英文地址,請注明出處:http://en.pswp.cn/news/370024.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

華為cor—al10_cor al10是華為什么型號 cor al10是華為啥型號

cor al10是華為榮耀Play。外觀方面&#xff0c;榮耀Play提供有星云紫&#xff0c;極光藍&#xff0c;幻夜黑三種基礎配色&#xff0c;以及幻夜黑與魅焰紅的酷玩版配色&#xff1b;拍照方面&#xff0c;榮耀Play具有1600萬AI雙攝像頭&#xff0c;前置攝像頭為1600萬像素&#xf…

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

一 迭代器 一 迭代的概念 #迭代器即迭代的工具&#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;而且無法實現跨平臺的一致性…

用CSS讓DIV上下左右居中的方法

例如 一個父div(w:100%;h:400px)中有一個子div(w:100px;100px;)。讓其上下左右居中。 方法一&#xff08;varticle-align&#xff09; 理念 利用表格單元格的居中屬性。 步驟 父div外層配置一個div&#xff0c;同時設置為表格元素 (display: table)&#xff0c;寬度為100%父…

功能性Java集合

如今&#xff0c;在功能上大肆宣傳&#xff0c;因此至少在Java集合方面&#xff0c;我將簡要介紹一下其中的功能。 我個人喜歡標準 集合API&#xff0c;但在某些情況下可能會很尷尬并添加其他詳細信息。 在Java 8的更高版本中&#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…

currentStyle、getComputedStyle 獲取樣式

style.height 獲取的是行間的樣式 currentStyle.height、getComputedStyle(elem,null).height 獲取的是 div 的 content 的寬高&#xff0c; clientHeight 獲取的是 contentpadding&#xff0c; offsetHeight 獲取的是contentpaddingborder。 <script> window.onload…

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…

Java基礎5一數組的常見應用算法

常用算法 1.冒泡排序: 原理&#xff1a;比較兩個相鄰的元素&#xff0c;將值大的元素交換至右端 示例: public static void bubbleSort(int[] a) {int n a.length;//總共進行n-1輪的比較for (int i 1; i < n; i) {for (int j 0; j < n - i; j) {if (a[j] > a[j 1]…

使用Xtend構建Vaadin UI

今天&#xff0c;我決定向Xtend打個招呼。 我希望學習一些新的編程語言。 選擇一個標準的清單并不多。 它必須是在JVM上運行的編程語言&#xff0c; 如果我不需要學習用于建筑應用的全新生態系統&#xff0c;那就太好了。 我已經檢查了幾個選項。 JVM的編程語言列表已不多了…

python 瀏覽器顯示本地文件夾_瀏覽器讀取本地文件

{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],"search_count":[{"count_phone":4,"count":4}]},"card":[{"des":"阿里云文件存儲NAS是一個可共享訪問&#xf…

p15頁

給你一個n*n的01矩陣&#xff0c;只能夠將0變成1&#xff0c;使得每個元素上下左右之和均是偶數&#xff0c; 比如 0 0 0 0 1 0 1 0 0>>>>1 0 1 0 0 0 0 1 0 一個轉變了3步 多實例T 然后一個n&#xff08;n<15&#xff09; 表示n*n的矩陣 …

html 登陸sql server,jsp實現注冊與登錄頁面+sqlsever2008

//index.jspString path request.getContextPath();String basePath request.getScheme()"://"request.getServerName()":"request.getServerPort()path"/";%>登陸用戶登陸用戶名&#xff1a;密 碼:注冊新用戶//Logon.jspString path req…

百度前端學院-基礎學院-第四課

今天是第四天&#xff0c;進度可以&#xff0c;表揚一下自己。 今天的課程目標是&#xff1a;掌握 CSS 稍微復雜的一些選擇器&#xff0c;還有背景&#xff0c;邊框等一些 CSS 樣式屬性。 CSS背景&#xff1a; 背景色&#xff1a;background-color:gray; 背景圖&#xff1a…

JUnit測試方法訂購

直到4.10版為止的Junit都使用反射API返回的測試類中測試方法的順序作為測試方法執行的順序– Class.getMethods&#xff08;&#xff09; 。 引用getMethods&#xff08;&#xff09;api的Javadoc&#xff1a; 返回的數組中的元素未排序&#xff0c;并且沒有任何特定順序。 …

html中padding和margin的區別和用法與存在的bug消除

關于margin&#xff1a;在需要border外側添加距離時。空白處不需要背景時。相連的兩個部分的地方需要加外邊的邊距時使用。 關于padding&#xff1a;在需要border內側添加距離時。空白處需要背景時。相連的兩個部分的地方需要加內部的邊距時使用。 IE6中雙邊距Bug&#xff1a; …

python發微信提醒天氣冷了注意保暖_2019天氣變冷的朋友圈說說 注意保暖的微信問候語...

1.天冷了&#xff0c;注意添加衣物&#xff0c;別著涼。可你還是著涼了。看你難受的樣子&#xff0c;我的心&#xff0c;唉&#xff0c;只有一句話能表達&#xff1a;小樣&#xff0c;你也有今天&#xff01;為了不讓我得逞&#xff0c;你要注意身體哦。2.天氣變涼要注意&#…

Fiddler抓包使用教程-QuickExec

轉載請標明出處&#xff1a;http://blog.csdn.net/zhaoyanjun6/article/details/73468287 本文出自【趙彥軍的博客】 在 Fiddler 中自帶了一個 QuickExec 命令行&#xff0c;用戶可以直接輸入并快速執行腳本命令。 常見命令 help 打開官方的使用頁面介紹&#xff0c;所有的命令…