只有累積,沒有奇蹟

2019年1月21日 星期一

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

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

使用說明
要驗證的 sample Code 如下,Example 類別有個 WorkTime 方法內容為只要工作超過 12 小時就會拋出自訂的 AngryException 錯誤訊息為我要森77了(幼稚)
public class Example
{
    public string Worktime(int hours)
    {
        if (hours > 12)
        {
            throw new AngryException("我森77!!");
        }

        // todo something
        return "正常";
    }

    public class AngryException : Exception
    {
        public AngryException(string message) : base(message)
        {
        }
        public override string Message
        {
            get { return "AngryException"; }
        }
    }

}
NUnit 2 
在 NUnit 2.x 針對驗證例外提供了 ExpectedException在要驗證的方法加上 attribute 指定要驗證的 exception 類別,如果需要驗證錯誤的訊息內容可加上 ExpectedMessage 參數,sample code 如下
[Test()]
[ExpectedException(typeof(AngryException))]
public void WorktimeTest_worktime_over15hour_ExpectedException()
{
    var ex = new Example();
    ex.Worktime(15);
}

[Test()]
[ExpectedException(typeof(AngryException), ExpectedMessage = "我森77!!")]
public void WorktimeTest_worktime_over15hour_ExpectedExceptionMsg()
{
    var ex = new Example();
    ex.Worktime(15);
}
NUnit 3 
在 NUnit 3 版本提供新的驗證例外方法 Assert.Throws 來取代 ExpectedException,使用委派來驗證是否有拋出指定的 exception,如果需要驗證非同步的例外也可以使用 Assert.ThrowsAsync使用上相當簡單請參考 sample code 如下
[Test()]
public void WorktimeTest()
{
    var ex = new Example();
    Assert.Throws<AngryException>(() => ex.Worktime(15));
}

[Test()]
public void WorktimeTest_Message()
{
    var ex = new Example();
    Assert.Throws<AngryException>(() => ex.Worktime(15), "我森77!!");
}

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

0 意見:

張貼留言

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

Design by Anders Noren | Blogger Theme by NewBloggerThemes.com