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

时间:2010-08-13 22:31:28

标签: c# exception-handling enterprise-library

我有一个做一些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))]单元测试以确保此方法符合规范。

我怎么能这样做?

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

2 个答案:

答案 0 :(得分: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使用的任何内容。

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

答案 1 :(得分:1)

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