Пустые возвращаемые типы / подпрограммы - старые новости. Я не делал возврат типа Void (если только я не был очень ленивым) в течение примерно 8 лет (со времени этого ответа, так что чуть раньше, чем этот вопрос был задан).
Вместо такого метода, как:
public void SendEmailToCustomer()
Создайте метод, который следует парадигме Microsoft int.TryParse ():
public bool TrySendEmailToCustomer()
Возможно, нет никакой информации, которую ваш метод должен возвращать для использования в долгосрочной перспективе, но возвращение состояния метода после того, как он выполняет свою работу, является огромной пользой для вызывающей стороны.
Кроме того, bool не единственный тип состояния. Существует множество случаев, когда ранее созданная подпрограмма могла фактически возвращать три или более различных состояния (хорошее, нормальное, плохое и т. Д.). В этих случаях вы просто используете
public StateEnum TrySendEmailToCustomer()
Тем не менее, хотя Try-Paradigm в некоторой степени отвечает на этот вопрос о том, как тестировать возврат void, существуют и другие соображения. Например, во время / после цикла «TDD» вы выполняете «Рефакторинг» и замечаете, что вы делаете две вещи с помощью вашего метода ... тем самым нарушая «Принцип единой ответственности». Так что об этом нужно позаботиться в первую очередь. Во-вторых, вы могли идентифицировать зависимость ... вы касаетесь "постоянных" данных.
Если вы делаете доступ к данным в рассматриваемом методе, вам необходимо выполнить рефакторинг в n-уровневую или n-слойную архитектуру. Но мы можем предположить, что когда вы говорите «Строки затем вставляются в базу данных», вы на самом деле имеете в виду, что вызываете слой бизнес-логики или что-то в этом роде. Я, мы будем считать это.
Когда ваш объект создается, вы теперь понимаете, что у вашего объекта есть зависимости. Это когда вам нужно решить, собираетесь ли вы делать инъекцию зависимостей на объект или метод. Это означает, что вашему Конструктору или рассматриваемому методу требуется новый параметр:
public <Constructor/MethodName> (IBusinessDataEtc otherLayerOrTierObject, string[] stuffToInsert)
Теперь, когда вы можете принять интерфейс вашего объекта уровня бизнес / данных, вы можете смоделировать его во время модульных тестов и не иметь никаких зависимостей или боязни "случайного" интеграционного тестирования.
Таким образом, в вашем живом коде вы передаете IBusinessDataEtc
объект REAL . Но в вашем модульном тестировании вы передаете IBusinessDataEtc
объект MOCK . В этом макете вы можете включить неинтерфейсные свойства, такие как int XMethodWasCalledCount
или что-то, чьи состояния обновляются при вызове методов интерфейса.
Таким образом, ваш модульный тест пройдет ваш метод (ы) в вопросе, выполнит любую логику и вызовет один или два или выбранный набор методов в вашем IBusinessDataEtc
объекте. Когда вы делаете свои утверждения в конце вашего модульного теста, у вас есть несколько вещей, чтобы проверить сейчас.
- Состояние подпрограммы, которая теперь является методом Try-Paradigm.
- Состояние вашего фиктивного
IBusinessDataEtc
объекта.
Для получения дополнительной информации об идеях внедрения зависимостей на уровне конструкции ... как они относятся к модульному тестированию ... посмотрите шаблоны проектирования Builder. Он добавляет еще один интерфейс и класс для каждого текущего интерфейса / класса, который у вас есть, но они очень маленькие и обеспечивают ОГРОМНОЕ увеличение функциональности для лучшего модульного тестирования.