2015-04-20 136 views
2

我已經看過有關單元測試的其他文章,但沒有看到實際測試異常時拋出的內容。主要目標是引發異常,並通過向助手類發送不良參數來檢查堆棧跟蹤的細節。測試異常並捕獲異常的詳細信息

由於原代碼沒有拋出異常,我決定做一些關於NUnit測試的在線研究,並且遇到了一段非常好的代碼,這段代碼比我編寫的代碼短得多,但用於檢查錯誤對象。我需要能夠在堆棧跟蹤中存在某些字符。

本來這是什麼代碼看起來像,但我必須承認它是不是很漂亮:

[Test] 
    public void TestExceptionHandling() 
    { 
     try 
     { 
      DoExceptionScenario(new SomeCustomRadioButtonControl(), FieldManager.GetField("access_mode")); 
     } 
     catch (Exception ex) 
     { 
      Assert.IsInstanceOf(typeof(CustomException), ex); 
      string details = Util.GetExceptionDetails((CustomException)ex); 
      Assert.IsTrue(details.Contains("Detail Name=\"ControlName\" Description=\"SomeCustomRadioButtonControl\"")); 
     } 
    } 

,你可能看到的問題是一堆誤報的方法可行。

另一種方式我修改了測試是這樣的:

[Test] 
    public void TestExceptionHandling() 
    { 
     Assert.That(() => DoExceptionScenario(new SomeCustomRadioButtonControl(), FieldManager.GetField("access_mode")), 
       Throws.TypeOf<CustomException>()); 
    } 

,如果沒有異常,則會失敗。但是,如果有一個例外,我該如何捕獲並檢查其內容?沿(在if聲明將在這種情況下工作)線的東西:

[Test] 
    public void ShouldControlNameBeListedInStackTrace() 
    { 
     bool exceptionStatus = Assert.That(() => DoExceptionScenario(new SomeCustomRadioButtonControl(), FieldManager.GetField("access_mode")), 
       Throws.TypeOf<CustomException>()); 

     if (exceptionStatus != true) 
     { 
      string details = Util.GetExceptionDetails((CustomException)ex); 
      Assert.IsTrue(details.Contains("detail name=\"controlname\" description=\"SomeCustomRadioButtonControl\""));    
     }    
    } 

回答

4

假設一個CustomException類,看起來像這樣。它沒有做更多的事情......只是重寫從基類Exception「消息」屬性:

public class CustomException : Exception 
{ 
    private string message; 

    public override string Message 
    { 
     get { return string.Format("{0}: {1}", DateTime.Now, message); } 
    } 

    public CustomException(string message) 
    { 
     this.message = message; 
    } 
} 

而且假設你有拋出異常的方法,比如這個:

public class ProductionClass 
{ 
    public void SomeMethod() 
    { 
     throw new CustomException("Oh noz!"); 
    } 
} 

以下是您可以在nUnit中使用的一些示例測試。你想要最後一個。

[TestFixture] 
public class MyTests 
{ 
    private ProductionClass p; 

    [SetUp] 
    public void Setup() 
    { 
     p = new ProductionClass(); 
    } 

    // Use the ExpectedException attribute to make sure it threw. 
    [Test] 
    [ExpectedException(typeof(CustomException)] 
    public void Test1() 
    { 
     p.SomeMethod(); 
    } 

    // Set the ExpectedMessage param to test for a specific message. 
    [Test] 
    [ExpectedException(typeof(CustomException), ExpectedMessage = "Oh nozzzz!")] 
    public void Test2() 
    { 
     p.SomeMethod(); 
    } 

    // For even more detail, like inspecting the Stack Trace, use Assert.Throws<T>. 
    [Test] 
    public void Test3() 
    { 
     var ex = Assert.Throws<CustomException>(() => p.SomeMethod()); 

     Assert.IsTrue(ex.StackTrace.Contains("Some expected text")); 
    } 
} 

Assert.Throws<T>方法適用於任何Exception。它執行括號中的委託並檢測是否拋出異常。

在上面的測試中,如果做了的拋出,那麼它也會測試指定內容的堆棧跟蹤。如果兩個步驟都通過,則測試通過。

+0

這是一件美麗的事情,我的朋友! – Risho

+0

很高興幫助。祝你好運! –