2012-01-31 45 views
1

我有单元测试具有此方法的类的方法如何使用静态类,没有Moles或Isolator的单元测试方法?

 public int GetHighestPriorityPriceRecordIndex(SearchAndExtractReply_2 priceInfoReply) 
    { 
     int index = 0; 

     var priceExposableColumn = GetPriceColumn(priceInfoReply, "LPCIsPriceExposable"); 

     var pricingSourceIDColumn = GetPriceColumn(priceInfoReply, "LPCPricingSourceID"); 

     var priceExposablePriority = new Dictionary<string, int> { { "Y", 2 }, { "N", 1 } }; 

     var pricingSourcePriority = new Dictionary<string, int> { { "USA", 5 }, { "EME", 4 }, { "ASI", 3 }, { "DER", 2 }, { "NUS", 1 } }; 

     if (priceExposableColumn.Value != null) 
      for (int i = 1; i < priceExposableColumn.Value.Length; i++) 
       if (priceExposablePriority[priceExposableColumn.Value[i]] > priceExposablePriority[priceExposableColumn.Value[index]] 
        && pricingSourcePriority[pricingSourceIDColumn.Value[i]] > pricingSourcePriority[pricingSourceIDColumn.Value[index]]) 
        index = i; 

     return index; 
    } 

    private static StringColumn GetPriceColumn(SearchAndExtractReply_2 priceInfoReply, string columnName) 
    { 
     return (StringColumn)SearchAndExtractReply_2_Extension.GetColumn(priceInfoReply, columnName); 
    } 

我想,这种方法使用静态类和方法 SearchAndExtractReply_2_Extension.GetColumn。 如何更好地重构此代码,以便我可以在没有Moles或Isolator的情况下测试此方法?或者更好地使用痣来隔离代码? 在此先感谢。

回答

2

如果可以,请重构。考虑到你仍然可以选择使小代码发生变化,使得Moles听起来有点矫枉过正。

关于那个重构。引入一个新的课程,唯一的责任是从SearchAndExtractReply_2对象中提取列。这是相当简单:

public interface IColumnExtractor 
{ 
    StringColumn GetPriceColumn(SearchAndExtractReply_2 source, 
     string columnName); 
} 

public class ColumnExtractor : IColumnExtractor 
{ 
    public StringColumn GetPriceColumn(SearchAndExtractReply_2 source, 
     string columnName) 
    { 
     return (StringColumn)SearchAndExtractReply_2_Extension.GetColumn(source, 
      columnName); 
    } 
} 

现在,无论你原来的方法提供这样的类实例(添加IColumnExtractor类型的新参数),或(通过构造函数注入例如)提供完全相同的提取到整个类。

public int GetHighestPriorityPriceRecordIndex(
    SearchAndExtractReply_2 priceInfoReply, IColumnExtractor columnExtractor) 
{ 
    // use extractor object instead of static method 
} 

然后你就可以去任何免费的模拟框架(如FakeItEasyMoq)。

2

如果你依赖于某些东西,它应该传递给方法。那么你的API是清楚的,你可以从外面告诉需要什么和可以嘲笑什么。这意味着您将建筑逻辑和业务逻辑分开。当与像Unity或Castle这样的依赖注入框架结合使用时,它会为您提供单元测试中很好的可测试代码,以及易于在生产环境中使用的代码。

我会为您的SearchAndExtractReply_2_Extension创建一个接口,然后将其作为参数传递给GetHighestPriorityPriceRecordIndex(或者,如果它在多个位置使用,则可能传递给构造函数)。然后,您可以模拟整个依赖关系,或者在进行集成测试时将“实际实现”传递给它。

+0

由于我udnderstood我需要你的依赖注入正确吗? – Serghei 2012-01-31 16:16:29

+0

是的,这将有助于使代码更加清晰,并且会为您提供接缝,您可以插入模拟以确保可以独立测试代码。 – 2012-01-31 16:22:17

+0

问题是我在一个大的遗留解决方案中工作,并且包含IoC容器需要重构大量代码和吨代码。 – Serghei 2012-01-31 16:29:41

相关问题