1

我有一个公共的方法和其运行取决于传递什么参数的公共方法,所以我的代码中的许多私有方法的类看起来类似:单元测试复杂的类有许多私有方法

public class SomeComplexClass 
{ 
    IRepository _repository; 

    public SomeComplexClass() 
     this(new Repository()) 
    { 
    } 

    public SomeComplexClass(IRepository repository) 
    { 
     _repository = repository; 
    } 


    public List<int> SomeComplexCalcualation(int option) 
    { 
     var list = new List<int>(); 

     if (option == 1) 
      list = CalculateOptionOne(); 
     else if (option == 2) 
      list = CalculateOptionTwo(); 
     else if (option == 3) 
      list = CalculateOptionThree(); 
     else if (option == 4) 
      list = CalculateOptionFour(); 
     else if (option == 5) 
      list = CalculateOptionFive(); 

     return list; 
    } 

    private List<int> CalculateOptionOne() 
    { 
     // Some calculation 
    } 

    private List<int> CalculateOptionTwo() 
    { 
     // Some calculation 
    } 

    private List<int> CalculateOptionThree() 
    { 
     // Some calculation 
    } 

    private List<int> CalculateOptionFour() 
    { 
     // Some calculation 
    } 

    private List<int> CalculateOptionFive() 
    { 
     // Some calculation 
    } 
} 

我想过几种方法来测试这个类,但它们都显得过于复杂或比我想的更多地暴露方法。选项到目前为止有:

  • 设置所有私有方法内部和用[组件:InternalsVisibleTo()]

  • 分离出所有的私有方法成一个单独的类和创建的接口。

  • 使所有的方法都是虚拟的,并在我的测试中创建一个从此类继承并重写方法的新类。

是否有任何其他选项用于测试上述类,这会更好地列出我所列出的内容?

如果你会选择我列出的其中一个,你可以解释为什么?

感谢

+0

这是切你的问题,但如果/ else结构令我奇怪。从设计的角度来看,您是否经常拥有调用多种类型计算的类的客户,或者一个客户通常只会调用一个选项? – 2010-04-29 15:44:20

+0

这是我的实际班级的简化版本,但许多客户通常会调用很多选项。 – lancscoder 2010-04-29 15:49:55

回答

7

您不需要更改接口来测试这些方法。只要全面测试的公共接口,以确保所有的私有方法进行测试:

void Test1() 
{ 
     new SomeComplexClass(foo).SomeComplexCalcualation(1); 
} 

void Test2() 
{ 
     new SomeComplexClass(foo).SomeComplexCalcualation(2); 
} 

等等...

您可以使用覆盖工具(如NCover用于.NET),以确保所有你想测试的代码实际上已经过测试。

3

如何OptionCalculators,到原来的类调度的工作?每个只有一个方法,CalculateOption,当然它会公开,因此很容易测试。

0

您应该只需要测试类/接口的公共方法。

你只需要确保你有足够的单元测试用例来彻底测试这些公共方法的所有不同行为(这将适当地超越私有方法)。

0

如果这些计算中的每一个都很复杂,那么每个计算是否真的是单一方法?如果这些计算共享代码,或者应该是多个方法,那么它就是您提到的接口/策略方法的一个参数,因此您可以测试每个步骤。

要考虑的另一件事:彻底行使一种公开方法是测试两件事情 a)ComputeOptionN代码正在工作,b)选项检查工作正常。

如果您直接输入整数,但不是理想的问题,特别是如果比较可能变得更加复杂,或者可能会变化。

0

@Carl是对的。这只不过是利用战略模式。将所有calculator s存储在一个数组中,将数组注入SomeComplexClass。这将允许你单独测试每个calculator本身和SomeComplexClass。现在,你可以这样做:

public List<int> SomeComplexCalcualation(int option) 
{ 
    return calculator.find(option); 
} 

很容易嘲笑calculator