将局部变量传递给同一类中的方法以实现可测试性?

时间:2014-05-16 16:28:46

标签: c# unit-testing

我有一个访问类本身的变量的方法。我想知道这是否是一个设计缺陷,因为现在我的单元测试依赖于那些设置的变量。将这些变量传递给方法是否奇怪/错误,即使该方法可以直接访问这些变量? (如果方法接受这些变量作为参数,那么单元测试也可以将自己的变量传递给方法。)

例如,以下是该类的本地变量:

private static List<string> _whitelistNames = GetWhitelistNamesFromConfig();
private static List<string> _blacklistNames = GetBlacklistNamesFromConfig();

方法看起来像这样:

    private static bool ThisProcessorHandlesThisFoo(Foo foo)
    {
        if (_whitelistNames.Count > 0)
        {
            // We're doing this instead of Contains() so we can ignore case sensitivity.
            bool found = ListContainsString(_whitelistNames, foo.Name, StringComparison.OrdinalIgnoreCase);

            // Some logging here

            return found;
        }

        if (_blacklistNames.Count > 0)
        {
            bool found = ListContainsString(_blacklistNames, foo.Name, StringComparison.OrdinalIgnoreCase);

            // Some logging

            return !found;
        }

        throw new InvalidOperationException("some message");
    }

为了做我建议的事情,我需要将方法签名更改为:

private static bool ThisProcessorHandlesThisFoo(Foo foo, List<string> whitelistNames, List<string> blacklistNames)

然后调用代码(在同一个类中)必须将局部变量传递给方法。这将允许我的测试代码发送自己的参数。我错过了什么吗?有一个更好的方法吗? (传递方法已经访问的参数似乎很奇怪。但也许这是一种很好的解耦技术。)

2 个答案:

答案 0 :(得分:1)

你不必担心这个。

您的单元测试应该测试您的类的接口(公共方法和属性),并且依赖于任何实现细节(如私有类属性)。这允许实现在不破坏其他代码的情况下进行更改(并且希望不会破坏现有测试)。

在实例化类时,应初始化这些私有静态字段(根据您的代码,它们具有初始化程序)。它们是否在为您的单元测试实例化时被初始化?它们应该是...这是一个普遍接受的想法,当一个对象的构造函数完成运行时,该类应该处于可用状态,并且你表明情况并非总是如此。

这是一个类似Dependency Injection之类的例子。然后,您将这些类型的东西传递给类的构造函数(或通过其他方法),并允许创建它的程序部分(正常程序或单元测试)将它们“注入”到类中。 / p>

答案 1 :(得分:1)

  1. 您不应该测试private方法,以测试覆盖所有课程的方式测试public方法。代码分支(包括private方法中的代码分支)。
  2. 我建议您更改方法签名(到ThisProcessorHandlesThisFoo(Foo foo, List<string> whitelistNames, List<string> blacklistNames))而不是使用字段。根据我的经验,这种方法使课程更容易阅读和维护。