使用JUnit的ExpectedException和@Rule測試自定義異常

異常測試

為什么要測試異常流? 就像所有代碼一樣,測試覆蓋率會在代碼和應該生成的業務功能之間寫一個合同,從而為您提供代碼的有效文檔 ,以及增加的盡早且經常強調功能的功能。 我不會介紹測試的許多好處,而是只關注異常測試。

有很多方法可以測試從一段代碼引發的異常流。 假設您有一個受保護的方法,該方法要求參數不為null。 您將如何測試該狀況? 引發異常時,如何防止JUnit報告失敗? 該博客涵蓋了幾種不同的方法使用JUnit的的ExpectedException使用JUnit的@rule功能實現的高潮。

“舊”方式

在不久的將來,測試異常的過程需要大量的樣板代碼,您可以在其中啟動try / catch塊,如果代碼未產生預期的行為,則報告失敗,然后捕獲異常以查找異常。具體類型。 這是一個例子:

public class MyObjTest {@Testpublic void getNameWithNullValue() {try {MyObj obj = new MyObj();myObj.setName(null);fail('This should have thrown an exception');} catch (IllegalArgumentException e) {assertThat(e.getMessage().equals('Name must not be null'));}}
}

從這個舊示例中可以看到,測試用例中的許多行只是為了支持缺少專門測試異常處理的功能。 使用try / catch方法的一個好處是可以測試特定消息和預期異常上的任何自定義字段 。 我們將通過JUnit的ExpectedException和@Rule注釋進一步探討這一點。

JUnit添加了預期的異常

JUnit通過添加@Test注釋字段“ expected”來響應用戶對異常處理的需求。 目的是,如果引發的異常類型與注釋中存在的異常類匹配,則整個測試用例將通過。

public class MyObjTest {@Test(expected = IllegalArgumentException.class)public void getNameWithNullValue() {MyObj obj = new MyObj();myObj.setName(null);}
}

從較新的示例中可以看到,樣板代碼要少得多,并且測試非常簡潔,但是存在一些缺陷 。 主要缺陷是測試條件太寬泛。 假設簽名中有兩個變量,并且兩個變量都不能為null,那么如何知道為IllegalArgumentException拋出了哪個變量呢? 當您擴展了Throwable并需要檢查字段的存在時會發生什么? 在繼續閱讀時,請記住這些,隨后將有解決方案。

JUnit @Rule和ExpectedException

如果查看前面的示例,可能會看到期望拋出IllegalArgumentException,但是如果您有一個自定義異常,該怎么辦? 如果要確保該消息包含特定的錯誤代碼或消息怎么辦? 這是JUnit真正出色的地方,它提供了專門為異常測試量身定制的JUnit @Rule對象。 如果您不熟悉JUnit @Rule,請在此處閱讀文檔 。

ExpectedException

JUnit提供了一個JUnit類ExpectedException,該類旨在用作@Rule。 ExpectedException允許您的測試聲明預期會出現異常,并為您提供一些基本的內置功能來清楚地表達預期的行為。 與@Test(expected)批注功能不同,ExpectedException類允許您通過Hamcrest匹配器庫測試特定的錯誤消息和自定義字段。

JUnit的ExpectedException的示例

import org.junit.rules.ExpectedException;public class MyObjTest {@Rulepublic ExpectedException thrown = ExpectedException.none();@Testpublic void getNameWithNullValue() {thrown.expect(IllegalArgumentException.class);thrown.expectMessage('Name must not be null');MyObj obj = new MyObj();obj.setName(null);}
}

如前所述,該框架允許您測試特定消息,以確保在測試專門尋找的情況下拋出異常。 當懷疑多個參數的可空性時,這將非常有用。

自定義字段

可以說,ExpectedException框架最有用的功能是能夠使用Hamcrest匹配器測試您的自定義/擴展異常。 例如,您有一個自定義/擴展的異常將被拋出到一個方法中,并且該異常內部有一個“ errorCode”。 如何在不從上面列出的try / catch塊中引入樣板代碼的情況下測試該功能? 定制匹配器怎么樣!

可以從以下網址獲得此代碼: https : //github.com/mike-ensor/custom-exception-testing

解決方案:首先是測試用例

import org.junit.rules.ExpectedException;public class MyObjTest {@Rulepublic ExpectedException thrown = ExpectedException.none();@Testpublic void someMethodThatThrowsCustomException() {thrown.expect(CustomException.class);thrown.expect(CustomMatcher.hasCode('110501'));MyObj obj = new MyObj();obj.methodThatThrowsCustomException();}
}

解決方案:自定義匹配器

import com.thepixlounge.exceptions.CustomException;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;public class CustomMatcher extends TypeSafeMatcher<CustomException> {public static BusinessMatcher hasCode(String item) {return new BusinessMatcher(item);}private String foundErrorCode;private final String expectedErrorCode;private CustomMatcher(String expectedErrorCode) {this.expectedErrorCode = expectedErrorCode;}@Overrideprotected boolean matchesSafely(final CustomException exception) {foundErrorCode = exception.getErrorCode();return foundErrorCode.equalsIgnoreCase(expectedErrorCode);}@Overridepublic void describeTo(Description description) {description.appendValue(foundErrorCode).appendText(' was not found instead of ').appendValue(expectedErrorCode);}
}

注意:請訪問https://github.com/mike-ensor/custom-exception-testing以獲取可用的Hamcrest Matcher,JUnit @Rule和ExpectedException的副本。

在那里,您可以快速概覽一下測試代碼引發的異常的不同方法,以及從自定義異常類中測試特定消息和字段的能力。 請具體說明您的測試用例,并嘗試針對您為測試設置的確切用例,請記住,測試可以避免引入副作用漏洞!

祝您編程愉快,別忘了分享!

參考:在Mike的站點博客上,從JCG合作伙伴 Mike 那里 ,使用JUnit的ExpectedException和@Rule測試自定義異常 。


翻譯自: https://www.javacodegeeks.com/2012/10/testing-custom-exceptions-with-junits.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/371554.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/371554.shtml
英文地址,請注明出處:http://en.pswp.cn/news/371554.shtml

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

相關文章

線程的工具類(Exchange)

public class Exchanger<V>extends Object 可以在對中對元素進行配對和交換的線程的同步點。每個線程將條目上的某個方法呈現給 exchange 方法&#xff0c;與伙伴線程進行匹配&#xff0c;并且在返回時接收其伙伴的對象。Exchanger 可能被視為 SynchronousQueue 的雙向形…

js 判斷瀏覽器是否64位

js判斷是否64位 瀏覽器 navigator.userAgent.match(/x64/i); 轉載于:https://www.cnblogs.com/fanlinglong/p/7298733.html

linux ss 軟件,linux ss 網絡狀態工具

ss是Socket Statistics的縮寫查看網絡狀態&#xff0c;經常用的命令&#xff1a; watch ss -lntss命令用于顯示socket狀態. 他可以顯示PACKET sockets, TCP sockets, UDP sockets, DCCP sockets, RAW sockets, Unix domain sockets等等統計. 它比其他工具展示等多tcp和state信…

Lambda項目:邁向多核及超越

周一下午在JavaOne 2011的希爾頓舊金山大宴會廳B上做了“ Project Lambda&#xff1a;邁向多核和超越”&#xff08;會議27400&#xff0c;不要與Brian Goetz的同名演講相混淆&#xff09; 的演示 。大宴會廳關閉&#xff0c;這是一個非常大型的非主題演講場地&#xff0c;并且…

Python 06-字典

字典是一種key-value的數據類型&#xff0c;就像日常用的字典&#xff0c;通過字母或者筆畫來查找對應頁的詳細內容。 字典是無序的&#xff0c;沒有順序。因為有key。 info {stu1001:wang er,stu1002:zhang san,stu1003:li si } print(info)#打印字典所有kv print(info[stu10…

hashMap 源碼解讀理解實現原理和hash沖突

hashMap 怎么說呢。 我的理解是 外表是一個set 數組&#xff0c;無序不重復 。 每個set元素是一個bean &#xff0c;存著一對key value 看看代碼吧 package test;import java.util.HashMap; import java.util.Map.Entry;public class HashMaptest {public static void main(Str…

浙江大學linux網絡通信,浙江大學鐘財軍副教授——“Wireless Powered Communication Networks”...

2016年5月17日&#xff0c;浙江大學鐘財軍副教授應徐正元教授邀請在中科大西區科技實驗樓東樓十層1011會議室做了一場題為“Wireless Powered Communication Networks”的學術報告。報告會由龔晨教授主持&#xff0c;共50余名師生參加。此次報告會得到了“中科院無線光電通信重…

自定義Spring Data JPA存儲庫

Spring Data是一個非常方便的庫。 但是&#xff0c;由于該項目是一個相當新的項目&#xff0c;因此功能不佳。 默認情況下&#xff0c;Spring Data JPA將基于SimpleJpaRepository提供DAO的實現。 在最近的項目中&#xff0c;我開發了一個定制的存儲庫基類&#xff0c;以便可以在…

[基礎]PeopleSoft中的作業和調度作業集合定義

PeopleSoft進程調度器可以使一個或多個進程作為一個組。這個組在PeopleSoft中被稱為作業(Job)。 PeopleSoft進程被定義為單個任務&#xff0c;程序或例程&#xff0c;例如cobol程序或AE程序或客戶端運行的SQR。 作業由一個或多個相同或不同類型的進程組成&#xff0c;他們作為一…

體驗 WebFont,網頁上的藝術字

在最新項目中&#xff0c;由于要頻繁使用藝術字&#xff0c;而用戶設備沒有此字體&#xff0c;因此以往的經驗都是使用圖片...所以在同事的矚目期許之下&#xff0c;我開始實驗研究這個問題的解決方案1. 直接使用字體文件font-face {font-family: xxxx;src: url(../img/漢儀秀英…

linux文件分別打包命令,Linux文件打包命令

15.1 gzipgzip(1)是GNU的壓縮程序。它只對單個文件進行壓縮。基本用法如下&#xff1a;$ gzip filename程序執行以后&#xff0c;文件名會變成filename.gz&#xff0c;而且一般情況下大小會比原文件要小。注意&#xff0c;程序并不新建一個新的文件filename.gz,而是將filename變…

Play 2.0框架和XA交易

XA事務非常有用&#xff0c;而且開箱即用&#xff0c;今天的Play 2.0不支持它們。 在這里&#xff0c;我展示了如何添加該支持&#xff1a; 首先&#xff0c;介紹一些XA有用的示例&#xff1a; –如果您使用來自兩個不同persistence.xml的實體&#xff0c;則JPA使用兩個物理連…

java代碼注釋規范

java代碼注釋規范 一、規范存在的意義 應用編碼規范對于軟件本身和軟件開發人員而言尤為重要&#xff0c;有以下幾個原因&#xff1a;1、好的編碼規范可以盡可能的減少一個軟件的維護成本 , 并且幾乎沒有任何一個軟件&#xff0c;在其整個生命周期中&#xff0c;均由最初的開…

win10 hyper-v 虛擬機ping不通宿主機問題

在Windows10 Hyper-V 中安裝 Linux (Centos6.9)虛擬機無法 ping 通宿主機 這種情況下關閉 Windows 防火墻就能ping通了&#xff0c;當然關閉防火墻不安全。所以需要 做以下步驟: 控制面板-》系統和安全-》Windows防火墻-》高級設置-》入站規則 啟用下圖被紅框選中的兩個選…

linux方法參數,Linux的sysctl?命令?參數

Linux內核通過/proc虛擬文件系統向用戶導出內核信息&#xff0c;用戶也可以通過/proc文件系統或通過sysctl命令動態配置內核。比如&#xff0c;如果我們想啟動NAT&#xff0c;除了加載模塊、配置防火墻外&#xff0c;還需要啟動內核轉發功能。我們有三種方法&#xff1a;1. 直接…

Java枚舉:您擁有優雅,優雅和力量,這就是我所愛!

當Java 8即將面世時&#xff0c;您確定您對Java 5中引入的枚舉很了解嗎&#xff1f; Java枚舉仍然被低估了&#xff0c;很可惜&#xff0c;因為它們比您想象的要有用&#xff0c;它們不僅僅用于通常的枚舉常量&#xff01; Java枚舉是多態的 Java枚舉是可以包含行為甚至數據的…

C#刪除和清空文件夾的程序

/// <summary>/// 清空指定的文件夾&#xff0c;但不刪除文件夾/// </summary>/// <param name"dir"></param>private void DeleteFolder(string dir){foreach (string d in Directory.GetFileSystemEntries(dir)){if (File.Exists(d)){try{…

2)網頁請求順序

&#xff08;1&#xff09;分析瀏覽器訪問一個網頁的完整流程邏輯過程&#xff1a;http&#xff1a;//www.abc.com/def/ 轉載于:https://www.cnblogs.com/xiaoyoucai/p/7306246.html

JavaOne 2012:非阻塞數據結構如何工作?

當我查看今天的日程安排時&#xff0c;我感到有些驚訝&#xff0c;并指出我目前計劃今天參加的所有會議都在希爾頓舉行。 當我意識到JavaOne演示文稿中大約有一半是在希爾頓酒店中并且似乎按路線大致定位時&#xff0c;這變得有些不足為奇了。 Tobias Lindaaker &#xff08; 新…

c語言箭頭指針的作用,C語言中,結構體成員變量的點和箭頭

C語言中&#xff0c;調用成員變量用點還是用箭頭&#xff0c;取決于當前的ID是指針還是結構體本身。如&#xff1a;typedef struct {float height;float weight;} Person;int main(int argc, char *argv[]) {Person jiushen;Person *lengleng (Person *)malloc(sizeof(Person)…