2012-01-13 58 views
9

如何模拟在C#单元测试中引发的异常?如何在单元测试中模拟抛出异常?

我希望能够100%覆盖我的代码,但我无法测试可能出现异常的代码。例如,我无法模拟可能发生的力量问题。

例如:

public void MyMethod() 
{ 
    try 
    { 
    ... 
    } 
    catch(OutOfMemoryException e) 
    { 
    ... 
    } 
    catch(RandomErrorFromDatabaseLayer e) 
    { 
    ... 
    } 
} 

我希望能够模拟任何一种例外的是在此方法中,应该被抓。
有没有任何图书馆可以帮助我解决这个问题?

编辑1: 任何帮助完成我问Moq?

+1

您的代码示例并不能真正说明你的问题。为什么你不能模拟电源故障?你是否试图“注入”会导致所提到的异常被抛出的条件?什么是真正的问题? – 2012-01-13 13:56:03

+0

是的,就像在http://stackoverflow.com/a/8851628/79379,但没有我摧毁一个数据库,以模拟数据库faluire。 – 2012-01-13 14:02:04

回答

8

您需要创建一个模拟对象来代表可以抛出这些异常的真实对象。然后,您可以创建测试,仅仅是这样的:

public void ExampleMethod() 
{ 
    throw new OutOfMemoryException(); 
} 

如果您正在使用依赖注入框架它与模拟代码代替真正的代码更加容易。

5

您需要的是stub - 将模拟您的代码的某些条件的对象。出于测试目的,您通常会将实际对象实现替换为存根(或其他类型的伪造对象)。你的情况,考虑:

public class MyClass 
{ 
    private IDataProvider dataProvider; 

    public void MyMethod() 
    { 
     try 
     { 
      this.dataProvider.GetData(); 
     } 
     catch (OutOfMemoryException) 
     { 
     } 
    } 
} 

现在,你正在测试应在一定程度上可配置类 - 让您可以轻松地与存根代替真正的DataProvider执行/测试时伪造了一个(像你说的,你不”不想破坏你的数据库 - 没有人愿意!)。这可以通过例如构造器注入(或者实际上,任何其他dependency injection技术)来实现。然后

您的测试是微不足道的(当异常被抛出一些虚构的要求来测试):

[Test] 
public void MyMethod_DataProviderThrowsOutOfMemoryException_LogsError() 
{ 
    var dataProviderMock = new Mock<IDataProvider>(); 
    dataProviderMock 
     .Setup(dp => dp.GetData()) 
     .Throws<OutOfMemoryException>(); 
    var myClass = new MyClass(dataProviderMock); 

    myClass.MyMethod(); 

    // assert whatever needs to be checked 
} 
相关问题