Модульное тестирование сложных классов со многими закрытыми методами - PullRequest
1 голос
/ 29 апреля 2010

У меня есть класс с одним открытым методом и многими закрытыми методами, которые запускаются в зависимости от того, какой параметр передается в открытый метод, поэтому мой код выглядит примерно так:

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

Я подумал о нескольких способах тестирования этого класса, но все они кажутся слишком сложными или предоставляют методы больше, чем мне бы хотелось. Возможные варианты:

  • Установите все закрытые методы для внутренних и используйте [Assembly: InternalsVisibleTo ()]

  • Разделите все приватные методы в отдельный класс и создайте интерфейс.

  • Сделайте все методы виртуальными, и в моих тестах создайте новый класс, который наследуется от этого класса и переопределите методы.

Есть ли другие варианты для тестирования вышеуказанного класса, которые были бы лучше того, что я перечислил?

Если вы выберете одну из тех, что я перечислил, вы можете объяснить, почему?

Спасибо

Ответы [ 5 ]

7 голосов
/ 29 апреля 2010

Вам не нужно менять интерфейс для тестирования этих методов. Просто тщательно протестируйте открытый интерфейс, чтобы убедиться, что все приватные методы протестированы:

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

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

и так далее ...

Вы можете использовать инструмент покрытия (например, NCover для .NET), чтобы убедиться, что весь код, который вы хотите протестировать, действительно протестирован.

3 голосов
/ 29 апреля 2010

Как насчет OptionCalculators, на который оригинальный класс отправляет работу? Каждый из них будет иметь только один метод, CalculateOption, и, конечно, он будет общедоступным и поэтому легко тестируемым.

0 голосов
/ 29 апреля 2010

@ Карл прав. Это не более, чем использование шаблона стратегии. Сохраните все calculator s в массиве, введите массив в SomeComplexClass. Это позволит вам самостоятельно тестировать каждый calculator и SomeComplexClass. Теперь вы можете сделать это:

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

Очень легко издеваться calculator

0 голосов
/ 29 апреля 2010

Если каждое из этих вычислений настолько сложное, действительно ли каждое из них представляет собой один метод? Если в этих вычислениях используется общий код или каждый из них должен содержать несколько методов, это аргумент в пользу подхода интерфейса / стратегии, который вы упомянули, поэтому вы можете протестировать каждый из этих шагов.

Еще одна вещь, которую нужно учитывать: тщательное использование одного открытого метода - это проверка двух вещей. а) что код ComputeOptionN работает, И б) что проверка опций работает правильно.

Не проблема, если вы буквально передаете целые числа, но не идеально, особенно если сравнение может стать более сложным, или если оно может измениться.

0 голосов
/ 29 апреля 2010

Вам нужно только протестировать открытые методы класса / интерфейса.

Вам просто нужно убедиться, что у вас достаточно юнит-тестов, чтобы тщательно протестировать все различные варианты поведения этих открытых методов (которые должны соответствующим образом изучить частные методы).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...