使静态类可测试的最佳方法是什么?

时间:2011-08-25 10:38:48

标签: unit-testing static inversion-of-control

在我的asp.net应用程序中,我有以下静态类来处理我的应用程序中的某些类具有依赖关系的查询字符串:

public static class QueryStringUtil
{
    public static int? GetStoreId()
    {
        return GetId(QueryStrings.StoreId);
    }

    public static string GetItemCode()
    {
        return Get(QueryStrings.ItemCode);
    }       

    private static string Get(string queryStringName)
    {
        return HttpContext.Current.Request.QueryString[queryStringName];
    }

    private static int? GetId(string queryStringName)
    {
        var queryString = Get(queryStringName);
        int queryStringParsed;
        return int.TryParse(queryString, out queryStringParsed) ? (int?)queryStringParsed : null;
    }
}

使这个类可测试的最佳方法是什么?

我知道的一种方法是重构它并使用它的接口创建一个单例实例类,并使依赖类接受我的单例类的接口。不确定这是我最好的选择。

另一种选择是使我的类成为带接口的普通类,然后创建一个单独的ServiceLocator类,负责将实例保存到所有应该像单例一样的类,例如我的QueryStringUtil,然后允许我的依赖类接受接口到我的IQueryStringUtil。

我能想到的第三个选项是不使用我的自定义服务定位器类而是使用IoC容器(例如Microsoft Unity),然后在IoC容器配置文件中保存单例实例并将其注入我的依赖类。

请告知您最佳选择以及原因。

非常感谢,

3 个答案:

答案 0 :(得分:2)

我非常喜欢IoC容器的最后一个选项。这是它的强大功能 - 它负责对象的生命周期和依赖性。

答案 1 :(得分:0)

我更喜欢IoC容器中的接口和普通类。您可以使用任何模拟框架创建发送到测试类/方法的实例和控件值。否则,您将被强制使用一些隔离框架,如TypeMock或Moles来模拟静态方法中的值。

答案 2 :(得分:0)

我知道我的观点不合适,但我认为你不是在谈论让这个课程可测试,而是关于使其他类依赖于它可测试

当您测试这些类时,可能有一个QueryStringUtil接口可能有用......?

然而,要尝试更一般的答案,任何类型的单身人士都是一种测试责任(它是一种全局状态,就像全局变量,文件或数据库一样)。 这个问题的一般答案是使用注入依赖关系(我认为这个名称比“控制反转”更精确和可理解,实际上根据不同的人意味着几个不同的东西)。 我不熟悉Asp.net,所以我不能告诉你使用哪个库,但是找到一个库没问题。

依赖注入将使用Singleton,但不会在您的代码中使用,您可以测试代码,就好像它不是Singleton