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
    }
}

我想了几种方法来测试这个类,但它们似乎都过于复杂,或者暴露的方法比我想要的要多。到目前为止的选项是:

  • 将所有私有方法设置为 internal 并使用 [assembly: InternalsVisibleTo()]

  • 将所有私有方法分离到一个单独的类中并创建一个接口。

  • 将所有方法设为虚拟,并在我的测试中创建一个继承自此类的新类并覆盖这些方法。

是否有任何其他选项可以测试上述课程,这会比我列出的更好?

如果您选择我列出的其中之一,您能解释一下原因吗?

谢谢

4

5 回答 5

8

您无需更改界面即可测试这些方法。只需彻底测试公共接口以确保测试所有私有方法:

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

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

等等...

您可以使用覆盖工具(例如.NET 的NCover)来确保您想要测试的所有代码都经过实际测试。

于 2010-04-29T15:37:51.313 回答
4

原始类将工作分派到的 OptionCalculators 怎么样?每个都只有一个方法,CalculateOption,当然它是公开的,因此很容易测试。

于 2010-04-29T15:37:11.437 回答
0

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

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

于 2010-04-29T15:39:37.793 回答
0

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

要考虑的另一件事:彻底执行一个公共方法是测试两件事 a) ComputeOptionN 代码是否正常工作,以及 b) 选项检查是否正常工作。

如果您从字面上传递整数,这不是问题,但并不理想,特别是如果比较可能变得更加复杂,或者它可能会改变。

于 2010-04-29T15:57:28.313 回答
0

@Carl 是对的。这无非是利用一种策略模式。将所有calculators 存储在一个数组中,将数组注入SomeComplexClass. 这将允许您单独对每个单元进行单元测试calculator,并且SomeComplexClass. 现在你可以这样做:

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

很容易模拟calculator

于 2010-04-29T19:39:11.387 回答