matchers依赖_Hamcrest Matchers的高级创建
matchers依賴
介紹
上一次 ,我討論了Hamcrest Matcher是什么,如何使用以及如何制作。 在本文中,我將解釋創建Hamcrest Matchers的更多高級步驟。 首先,我將分享如何使您的匹配器更易于類型安全,然后介紹無狀態匹配器的一些技術,最后是如何減少測試類的大量靜態導入。 我還將給出一些有關命名靜態工廠方法的快速提示。
類型安全匹配器
您可能已經在上次開發的matchs()方法中注意到了,我在注釋中指出,我曾使用“ yoda條件”來避免null檢查和類型檢查。 首先,自己對yoda條件進行一些研究不會有什么壞處(我可能有一天會發表一篇有關它的文章,但不能保證),但是這里要注意的最大事情是某種類型檢查和需要空檢查。 這是因為matchs()方法接受一個對象,而不是泛型參數中指定的類型。
如Hamcrest的文檔中所述:
此方法與Object匹配,而不是與通用類型T匹配。這是因為Matcher的調用者在運行時不知道類型是什么(由于Java通用類型已擦除類型)。
因此,我們需要確定傳入的對象的類型。此外,我們還應確保沒有傳入任何空值(除非我們的特定Matcher可以這樣做,但這非常罕見),或者在至少要確保傳入的null不會導致NullPointerException。
但是有一種更簡單的方法:TypeSafeMatcher。 如果擴展該類而不是BaseMatcher類,它將為您執行類型檢查和null檢查,然后將對象傳遞給僅采用泛型指定類型的匹配方法。
定義TypeSafeMatcher非常類似于我們上次定義Matcher的方式,但有一些區別:除了覆蓋matchs()之外,您還可以替代使用通用類型而不是Object的matchesSafely()。 而不是覆蓋describeMismatch(),而是覆蓋describeMismatchSafely()。 可能沒有一個新的describeTo()可能令人驚訝,但是看到它除了Description之外沒有其他內容,因此不需要類型安全的版本。
否則,創建TypeSafeMatcher幾乎是相同的。
不過,我不得不提我上周忘記的事情。 定義自己的Matcher的人不需要重寫describeMismatch()或describeMismatchSafely()方法。 BaseMatcher和TypeSafeMatcher都具有那些方法的默認實現,這些方法的簡單實現是僅輸出“ was item.toString() ”(如果TypeSafeMatcher獲得錯誤類型的項,則“ was of itemClassName ( item.toString()” )”。
這些默認實現通常足夠好,但是如果要使用的類型沒有toString()的有用實現,則使用您自己的不匹配消息來描述該項目的問題顯然更有用。 即使類具有不錯的toString()實現,我也總是這樣做,因為它可以更快地解決問題。
有關其他可擴展匹配器類的說明
Hamcrest核心庫中還有其他幾個Matcher類,供用戶從中擴展。 這些有幾種口味。
首先,是CustomMatcher和CustomTypeSafeMatcher。 這些設計用于通過匿名類一次性創建Matchers。 他們可能是有用的,但我更愿意總是在情況下,正確執行我曾經確實需要它一次。
接下來,有DiagnosingMatcher和TypeSafeDiagnosingMatcher,它們使您可以在match()方法中創建不匹配描述。 這似乎是用一塊石頭殺死兩只鳥的好方法,但是我有幾塊牛肉:1)它違反了SRP 2)如果存在不匹配,它再次調用matchs()方法只是為了填充在不匹配說明中。 因此,第一個調用忽略獲取描述,第二個調用忽略匹配。
您可以擴展的最后一個特殊的Matcher是FeatureMatcher。 這可能非常有用,但要理解起來很復雜(我不確定自己是否正確理解–直到我嘗試自己動手做一個或閱讀如何做一個為止)。 如果我弄清楚并獲得了很好的理解,我將在這里為您寫另一篇文章。
無狀態匹配器
任何不需要將任何內容傳遞給其構造函數的Matcher(因此,它是靜態工廠方法)都是無狀態Matcher。 它們與其他Matcher相比有一個很小的優勢,因為您只需要在任何時候存在一個實例,就可以在需要使用該Matcher的任何時間重用它。
這是一個非常簡單的補充。 您需要做的就是創建該類的靜態實例,并使您的靜態工廠返回該實例,而不是調用構造函數。 庫實際附帶的IsEmptyString Matcher可以做到這一點(上一次我們的示例沒有這樣做,但是為了簡單起見)。
減少靜態進口數量
用Hamcrest Matchers編寫了相當多的測試后,您可能會注意到文件頂部有很多靜態導入。 一段時間后,這可能會成為很大的麻煩事,所以讓我們看一下可以減輕此問題的方法。
實際上,這幾乎與上一個解決方案一樣簡單。 您可以通過創建實質上為您執行此操作的新類來減少靜態導入。 這個新類具有煩人的靜態導入,但隨后定義了自己的靜態工廠方法來委托給原始對象。 這是將一些核心Matchers組合到一個地方的示例:
import org.hamcrest.core.IsEqual; import org.hamcrest.core.IsNull; import org.hamcrest.core.IsSame; import org.hamcrest.Matcher;public class CoreMatchers {public static Matcher equalTo(T object) {return IsEqual.equalTo(object);}public static Matcher notNullValue() {return IsNull.notNullValue();}public static Matcher notNullValue(Class type) {return IsNull.notNullValue(type);}public static Matcher nullValue() {return IsNull.nullValue();}public static Matcher nullValue(Class type) {return IsNull.nullValue(type);}public static Matcher sameInstance(T target) {return IsSame.sameInstance(target);}public static Matcher theInstance(T target) {return IsSame.theInstance(target);} }然后,要使用任何或所有Matcher,只需靜態導入CoreMatchers。*還有一種生成這些組合Matcher類的方法,如官方Hamcrest教程所示 。 我不會繼續討論它,因為它不在本文討論范圍之內,而且我也不喜歡它。
結束提示:命名
如果您閱讀了官方的Hamcrest教程和/或查看了內置的Matchers,您可能會注意到靜態工廠方法的命名趨勢。 通用語法匹配“斷言testObject是factoryMethod ”。 方法名稱的語法通常設計為可以在“ is”之前使用的當前時態動作。在命名自己的靜態工廠方法時,通常應遵循此約定,但實際上我建議將“ is”放入名稱中已經。 這樣,Matcher的用戶無需將您的方法嵌套在is()方法內。 但是,如果執行此操作,則還需要創建反函數。 允許使用is()方法包裝Matcher的原因是,因此您也可以將其包裝在not()方法中,以測試已經測試的內容的逆函數。 這將導致類似“斷言testObject不是factoryMethod ”的句子。如果您認為遵循約定對特定的Matcher過于嚴格,則只需確保使用當前的時態操作測試即可。 例如,我做了一個匹配器,檢查是否拋出了一個異常,該異常的靜態工廠方法是throwsA()。 我只是不喜歡將它命名為throwingA()以便與“ is”一起使用。 但是,如果再次違反約定,則必須確定要創建一個靜態靜態工廠方法。 例如,如果您要實現自己的逆工廠,最簡單的方法通常是用not()包裝正工廠。 因此,我的nottThrowA()方法將返回not(throwsA())。 不過要小心:有時候,將正負誤轉實際上并不能給出您想要的正確逆。
奧托羅
好吧,這就是我為您準備的。 如果您想讓我繼續談論Hamcrest Matchers,請在評論中告訴我。 否則,您可以在其github頁面上的Hamcrest Matchers上進行自己的研究。下周,我將討論如何讓您的Hamcrest Matchers以類似于AssertJ斷言的流暢方式檢查多個事情。
翻譯自: https://www.javacodegeeks.com/2015/01/advanced-creation-of-hamcrest-matchers.html
matchers依賴
總結
以上是生活随笔為你收集整理的matchers依赖_Hamcrest Matchers的高级创建的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 狂野之血安卓破解版下载(狂野之血安卓)
- 下一篇: 灵魂小组盒子(灵魂小组ddos)