只有累積,沒有奇蹟

2019年1月21日 星期一

[UnitTest] NUnit 測試例外 exception - 使用 Assert.Throws

前言
介紹了如何使用 NUnit 撰寫單元測試、使用 TestCase 處理參數化方法測試不同情境,如果寫單元測試時想要驗證例外狀況時該怎麼處理 ? NUnit 分別在 NUnit 2 & 3 中提供 ExpectedException、Assert.Throws 讓開發者處理測試例外的情境,以下簡單分享如何使用

使用說明
要驗證的 sample Code 如下,Example 類別有個 WorkTime 方法內容為只要工作超過 12 小時就會拋出自訂的 AngryException 錯誤訊息為我要森77了(幼稚)
  1. public class Example
  2. {
  3. public string Worktime(int hours)
  4. {
  5. if (hours > 12)
  6. {
  7. throw new AngryException("我森77!!");
  8. }
  9.  
  10. // todo something
  11. return "正常";
  12. }
  13.  
  14. public class AngryException : Exception
  15. {
  16. public AngryException(string message) : base(message)
  17. {
  18. }
  19. public override string Message
  20. {
  21. get { return "AngryException"; }
  22. }
  23. }
  24.  
  25. }
NUnit 2 
在 NUnit 2.x 針對驗證例外提供了 ExpectedException在要驗證的方法加上 attribute 指定要驗證的 exception 類別,如果需要驗證錯誤的訊息內容可加上 ExpectedMessage 參數,sample code 如下
  1. [Test()]
  2. [ExpectedException(typeof(AngryException))]
  3. public void WorktimeTest_worktime_over15hour_ExpectedException()
  4. {
  5. var ex = new Example();
  6. ex.Worktime(15);
  7. }
  8.  
  9. [Test()]
  10. [ExpectedException(typeof(AngryException), ExpectedMessage = "我森77!!")]
  11. public void WorktimeTest_worktime_over15hour_ExpectedExceptionMsg()
  12. {
  13. var ex = new Example();
  14. ex.Worktime(15);
  15. }
NUnit 3 
在 NUnit 3 版本提供新的驗證例外方法 Assert.Throws 來取代 ExpectedException,使用委派來驗證是否有拋出指定的 exception,如果需要驗證非同步的例外也可以使用 Assert.ThrowsAsync使用上相當簡單請參考 sample code 如下
  1. [Test()]
  2. public void WorktimeTest()
  3. {
  4. var ex = new Example();
  5. Assert.Throws<AngryException>(() => ex.Worktime(15));
  6. }
  7.  
  8. [Test()]
  9. public void WorktimeTest_Message()
  10. {
  11. var ex = new Example();
  12. Assert.Throws<AngryException>(() => ex.Worktime(15), "我森77!!");
  13. }

ExpectedException 移轉
在 NUnit 3 已無法使用 ExpectedException搜尋原因後在 Why was ExpectedExceptionAttribute removed 中有提到可能的原因為 ExpectedException was removed because it encourages bad practices and it was generally felt that removing it helped developers fall into the pit of success.,Assert.Throws 與 ExpectedException 相較之下,在撰寫單元測試時更明確的指出預期錯誤的代碼與模組如果之前是使用 NUnit 2 ExpectedException 驗證例外狀況可以使用 ExpectedException 及 NUnit.That.Resharper.Plugin 進行移轉的動作,有需要的人可以自行研究看看

參考
NUnit
ExpectedExceptionAttribute
Assert.Throws
nunit issues 799

Related Posts:

  • [.NET] Default 和 NativeImage 資料夾問題 收到同事反應公司 Server C:\ 硬碟空間嚴重不足,確認後發現 C:\errors 資料空間占了 25g 而且還以驚人的速度成長中,進到資料夾底下查看分 Default 與 NativeImage folder 存放各種應用程式 Log ,如下圖所示 其中竟然還有 w3wp.exe,到底這些是如何記錄的呢 ? 本篇文章簡單記錄解決問題的過程 解決方案 為了追根究柢,點開其中 w3wp.exe 資料… Read More
  • [.NET] 字串加密 MD5、SHA1 常在開發中遇到需要將特定資料加密的動作,在儲存到資料庫中(比如說網站用戶的密碼加密後存到資料庫中,用戶在登入時,在把用戶輸入的密碼進行加密,再與資料庫密碼欄位比較是否一致)在.NET Framework中,可以透過 System.Security.Cryptography 命名空間來產生加密演算法的金鑰(註一),在用雜湊值(Hash Value)的加密方式達到目的,雜湊演算法將任意長度的二進位值對應到固定長度較小的二進位值,稱為雜湊值 (Ha… Read More
  • [C#] Named Arguments 具名引數前言  同事在開發專案時詢問某 method 有多個參數,有些參數是選擇輸入有預設值,因參數太多是否有方法可以指定參數名字 ? 否則一堆有設定預設值的在閱讀代碼會造成困擾,不小心也可能傳入錯誤變數,聽到當下建議抽成一個 Model 這樣更容易維護,但他表示由於引用的方法過多會擔心會牽一髮動全身,會有不可預期和毀滅性的災害發生,因此可以使用 具名引數 named arguments 來指定需要傳入的… Read More
  • [UnitTest] 如何測試目標方法中含有 static method 代碼 ? 情境 由於部門過去的 專案幾乎都沒有加上單元測試進行保護,主管在新的一年規劃中開發代碼更有品質,希望開發的專案加上新功能或是修改時要加上單元測試,有些 Legacy Code 寫法是屬於一條龍式的 「義大利麵式碼」特別有親切感(大誤,遇到這種就需要先重構 (refactor) 後物件化比較好寫單元測試,今天主題是單元測試中要被測試的 method 中常常會有相依於某個 Static method,在寫 Code 時用… Read More
  • [.NET] ASP.NET 狀態管理(State Management):ViewState Web應用程式是沒有狀態(Stateless)的,從前面介紹的文章(Application、Page Life-Cycle)可以了解到,每次用戶端發送請求(Request)到伺服器端時,都會建立Web網頁類別的新執行個體。由於每個請求都是新的個體,這也代表每次來回存取時,網頁及控制項的資訊將會遺失。例如,根據預設,當使用者在網頁textbox控制項輸入「Hello world」,按下按鈕送出後,這項資訊就會傳送到伺服器。但伺服器在回傳(Res… Read More

0 意見:

張貼留言

Copyright © 2025 m@rcus 學習筆記 | Powered by Blogger

Design by Anders Noren | Blogger Theme by NewBloggerThemes.com