2015-04-20 31 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

很高兴帮助。祝你好运! –