2011-08-25 55 views
1

在我的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。

我能想到的第三个选择是不使用我的Custom Service Locator类而是使用IoC容器(例如Microsoft Unity),然后在IoC容器配置文件中保存一个单例实例并将其注入到依赖类中。

请告诉你最好的选择,为什么。

非常感谢,

回答

2

我真的很喜欢与IoC容器中的最后一个选项。这是它的力量 - 它负责你的对象的生命周期和依赖关系。

+0

谢谢;哪个IoC容器会推荐最佳性能? –

+1

看这里 - http://stackoverflow.com/questions/21288/which-net-dependency-injection-frameworks-are-worth-looking-into –

0

我更喜欢IoC容器中的接口和普通类。您可以使用任何模拟框架创建实例和控制值,并将其发送给您测试的类/方法。否则,你将被迫使用像TypeMock或Moles这样的隔离框架来模拟静态方法中的值。

0

我知道我离题,但我认为你不是在说让这个类可测试,而是关于使其他类依赖于它可测试

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

但是,要尝试更一般的答案,任何类型的单例都是测试责任(它是全局状态的一种形式,就像全局变量,文件或数据库一样)。 这个问题的一般答案是使用注入依赖关系(我认为这个名称比“Inversion of Control”更精确,也更易于理解,实际上这意味着根据不同的人做出不同的事情)。 我对Asp.net并不熟悉,所以我不能告诉你要使用哪个库,但找到一个库就没有问题。

依赖注入将使用单例,但不在您的代码中,所以您可以测试您的代码,就好像它不是Singleton一样。

相关问题