Как создать тест на основе состояния для метода, который вызывает другие методы в том же классе?

StackOverflow https://stackoverflow.com/questions/1519882

  •  19-09-2019
  •  | 
  •  

Вопрос

У меня есть следующий код (который я упростил для вопроса):

    public void HandleModeInit(int appMode){
        switch(appMode){
            Case 1:
                DoThis();
            Case 2:
                DoThat();
            Case 3:
                //no mode 3
            Case 4:
                DoSomethingElse();
            Case else:
                //do nothing
        }
    }

Как бы вы выполнили модульное тестирование этого метода, не превращая его в интеграционный тест (где вы в конечном итоге проверяете, что делают DoThis(), DoThat() и DoSomethingElse())?Поскольку эти вызовы методов выполняются для методов в пределах тот же класс, что и HandleModeInit(), как бы вы это проверили?

Хотя в идеале вызовы методов должны быть извлечены в другой класс, что, если этот шаг не имеет никакого смысла?

Это было полезно?

Решение

Если у вас есть контроль над тем, что передается в этот метод, я бы передал интерфейс, который принимает appmode в качестве аргумента, который является AppModeImplementationFactory.Целью этой фабрики является создание AppModeImplementations.Фабрика будет выглядеть следующим образом:

public class AppModeImplementationFactory: IAppModeFactory
{
   public IAppModeImplementation Create(int appMode)
   {
      // switch case goes here to create the appropriate instance
   }
}

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

Надеюсь это поможет

Другие советы

Вместо использования оператора switch/case для переключения режимов приложения вы можете создать интерфейс под названием IAppMode (я предполагаю, что вызывающая сторона может решить, какой объект создать, который правильно реализует IAppMode, поскольку они уже передают int для представления приложения). Режим).

Ваш вызывающий объект передаст объект IAppMode, а затем ваш метод сможет вызвать метод DoThis() класса IAppMode.

Затем вы можете создать фиктивный объект, реализующий IAppMode, и внедрить его в метод во время тестирования.

Это упрощает ваш код (это можно сделать с помощью шаблонов проектирования) и облегчает тестирование.

Я понимаю (особенно, если вы это заметили), что код упрощен, но если вы не тестируете то, что в этом случае делают вызываемые методы, что вы на самом деле тестируете?Значение appMode?

Как именно это атаковать, сказать сложно (если вообще возможно), не зная того, что происходит внутри вызываемых методов.Делают ли они какие-либо исходящие вызовы (во внешние службы, базу данных и т. д.), которые можно высмеять?Если да, то это может быть шагом вперед.Если они содержат только поведение, инкапсулированное в классе, возможно, они изменяют какое-то значение свойства, которое вы можете проверить при вызове HandleModeInit возвращается?

Обычно я не сторонник изменения дизайна моего кода с единственной целью сделать его более тестируемым, но одним из подходов было бы отделить открытый интерфейс вашего класса от внутренних элементов, а затем определить внутренний интерфейс как, например, интерфейс.Таким образом, вы открываете возможность издеваться над внутренними органами.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top