2010-08-13 68 views
2

我有一个做一些IO通常看起来像这样的方法:单元测试 - 不包括捕捞

public bool Foo() 
{ 
    try 
    { 
     // bar 

     return true; 
    } 
    catch (FileNotFoundException) 
    { 
     // recover and complete 
    } 
    catch (OtherRecoverableException) 
    { 
     // recover and complete 
    } 
    catch (NonRecoverableException ex) 
    { 
     ExceptionPolicy.HandleException(ex, "LogException"); 
     return false; 
    } 
} 

的方法不是关键任务的完成,也有外部的恢复步骤 - 并且抛出NonRecoverableException相对常见 - 规范中它返回false,报告'此时无法完成',并且处理也随之移动。 NonRecoverableException不会使程序处于无效状态。

当我的单元测试,而这些例外之一被抛出,我得到

Activation error occured while trying to get instance of type ExceptionPolicyImpl 

而且我想抑制有利于获得实际/原始异常信息而不是错误EntLib无法记录(并且实际上强制执行NonRecoverableException并且有一个[ExpectedException(typeof(NonRecoverableException))]单元测试,以确保此方法符合规范

我该如何解决这个问题?

编辑 使用预处理指令并不理想,因为我讨厌在代码库中看到特定于测试的代码。

回答

10

使用Entlib静态外观的代码的可测试性很难。在不改变你的代码的情况下,你唯一的答案就是将一个app.config文件添加到你的测试程序集中,并用一个无用的策略来设置Entlib异常块。

但是,在Entlib 4(和5中,我看到您正在使用)还有另一种方法。我们专门为所有块添加了一个实例入口点,以改进可测试性故事。对于异常块,该实例是ExceptionManager。使用它非常简单。获取一个异常管理器实例到你的类型中,然后调用它而不是ExceptionPolicy。事情是这样的:

public class Whatever { 
    private ExceptionManager exm; 

    public Whatever(ExceptionManager exm) { this.exm = exm; } 

    public bool Foo() { 
     try { 
      ... do whatever ... 
     } 
     catch(NonRecoverableException ex) { 
      exm.HandleException(ex, "LogException"); 
      return false; 
     } 
    } 
} 

现在你已经有了,在那里,你可以模拟出ExceptionManager(它是一个抽象基类)基本测试期间无操作它,无论是手动或使用模拟对象框架。

如果您不想强制用户使用DI容器,你可以添加一个默认的构造函数获取当前异常管理:

public class Whatever { 
    private ExceptionManager exm; 

    public Whatever() : this(EnterpriseLibraryContainer.Current.GetInstance<ExceptionManager>()) { }   
    public Whatever(ExceptionManager exm) { this.exm = exm; } 
} 

最终用户使用默认的构造函数,你的测试使用一个接受一个显式的ExceptionManager,你有你的钩子嘲笑任何Entlib使用。

所有块现在都有这些“经理”类(无论如何它们都有意义)。

+0

那好吧;太棒了。非常感谢你。我打算将此标记为已接受,但在一天左右时间内,希望您能得到更多赞扬以获得如此好的答案。 – 2010-08-17 04:02:16

1

嗯,你可以重构代码,将所有内容放在try块中的一个单独的方法中,并配置测试来调用它而不是现有的方法?

+0

我认为这是一个好主意,但它是我正在创建的一个库函数,我希望尽可能保持界面的清洁。 – 2010-08-14 22:38:11

+0

让它变得私密还是内部? – Doobi 2010-08-14 22:45:47