使用entlib进行单元测试 - 不包括捕获量

Ste*_*ers 2 c# enterprise-library exception-handling

我有一个方法可以做一些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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

当我进行单元测试时,抛出其中一个异常,我得到了错误

Activation error occured while trying to get instance of type ExceptionPolicyImpl
Run Code Online (Sandbox Code Playgroud)

而且我想压制它,而不是获取实际/原始异常信息,而不是EntLib无法记录(并且,实际上强制NonRecoverableException并且具有[ExpectedException(typeof(NonRecoverableException))]单元测试以确保这种方法符合规范.

我怎么能这样做?

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

Chr*_*res 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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在你已经有了它,你可以模拟出ExceptionManager(它是一个抽象的基类),在测试过程中基本上没有操作它,无论是手动还是使用模拟对象框架.

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

public class Whatever {
    private ExceptionManager exm;

    public Whatever() : this(EnterpriseLibraryContainer.Current.GetInstance<ExceptionManager>()) { }        
    public Whatever(ExceptionManager exm) { this.exm = exm; }
}
Run Code Online (Sandbox Code Playgroud)

最终用户使用默认构造函数,您的测试使用接受显式ExceptionManager的测试,并且您可以使用钩子来模拟Entlib使用的任何内容.

现在所有的块都有这些"管理器"类(无论如何它们都有意义).