Каков наилучший способ модульного тестирования метода, который ничего не возвращает? Конкретно в с #.
Что я действительно пытаюсь проверить, так это метод, который берет файл журнала и анализирует его для конкретных строк. Строки затем вставляются в базу данных. Ничего из того, что не было сделано раньше, но, будучи ОЧЕНЬ новым для TDD, я задаюсь вопросом, возможно ли это проверить или это то, что на самом деле не было проверено.
c#
unit-testing
jdiaz
источник
источник
Ответы:
Если метод ничего не возвращает, это либо одно из следующих
Обязательные методы - вы можете проверить, действительно ли задание было выполнено. Проверьте, действительно ли произошло изменение состояния. например
можно проверить, проверив, действительно ли баланс после отправки этого сообщения меньше первоначального значения по dAmount
Информационные методы - редко встречаются в качестве члена открытого интерфейса объекта ... и, следовательно, обычно не тестируются модулем. Однако, если необходимо, Вы можете проверить, выполняется ли обработка уведомления. например
можно проверить, проверив, отправляется ли электронное письмо
Опубликуйте более подробную информацию о вашем фактическом методе, и люди смогут ответить лучше.
Обновление : ваш метод делает 2 вещи. Я бы на самом деле разделил его на два метода, которые теперь можно независимо протестировать.
String [] можно легко проверить, предоставив первому методу фиктивный файл и ожидаемые строки. Второй вариант немного сложен. Вы можете использовать Mock (google или search stackflowflow на платформах mocking), чтобы имитировать БД, или поразить реальную БД и убедиться, что строки были вставлены в нужное место. Проверьте эту ветку на наличие хороших книг ... Я бы порекомендовал прагматическое модульное тестирование, если вы в затруднении.
В коде это будет использоваться как
источник
Проверьте его побочные эффекты. Это включает:
Конечно, есть предел тому, сколько вы можете проверить. Например, вы не можете проверить все возможные входные данные. Тестируйте прагматично - достаточно, чтобы дать вам уверенность в том, что ваш код спроектирован надлежащим образом и реализован правильно, и достаточно, чтобы выступить в качестве дополнительной документации для того, что может ожидать вызывающая сторона.
источник
Как всегда: проверьте, что метод должен делать!
Должно ли это изменить глобальное состояние (ну, запах кода!) Где-нибудь?
Должен ли он позвонить в интерфейс?
Должно ли оно вызывать исключение при вызове с неправильными параметрами?
Должен ли он вызывать исключения при вызове с правильными параметрами?
Должно ли это ...?
источник
Пустые возвращаемые типы / подпрограммы - старые новости. Я не делал возврат типа Void (если только я не был очень ленивым) в течение примерно 8 лет (со времени этого ответа, так что чуть раньше, чем этот вопрос был задан).
Вместо такого метода, как:
Создайте метод, который следует парадигме Microsoft int.TryParse ():
Возможно, нет никакой информации, которую ваш метод должен возвращать для использования в долгосрочной перспективе, но возвращение состояния метода после того, как он выполняет свою работу, является огромной пользой для вызывающей стороны.
Кроме того, bool не единственный тип состояния. Существует множество случаев, когда ранее созданная подпрограмма могла фактически возвращать три или более различных состояния (хорошее, нормальное, плохое и т. Д.). В этих случаях вы просто используете
Тем не менее, хотя Try-Paradigm в некоторой степени отвечает на этот вопрос о том, как тестировать возврат void, существуют и другие соображения. Например, во время / после цикла «TDD» вы выполняете «Рефакторинг» и замечаете, что вы делаете две вещи с помощью вашего метода ... тем самым нарушая «Принцип единой ответственности». Так что об этом нужно позаботиться в первую очередь. Во-вторых, вы могли идентифицировать зависимость ... вы касаетесь "постоянных" данных.
Если вы делаете доступ к данным в рассматриваемом методе, вам необходимо выполнить рефакторинг в n-уровневую или n-слойную архитектуру. Но мы можем предположить, что когда вы говорите «Строки затем вставляются в базу данных», вы на самом деле имеете в виду, что вызываете слой бизнес-логики или что-то в этом роде. Я, мы будем считать это.
Когда ваш объект создается, вы теперь понимаете, что у вашего объекта есть зависимости. Это когда вам нужно решить, собираетесь ли вы делать инъекцию зависимостей на объект или метод. Это означает, что вашему Конструктору или рассматриваемому методу требуется новый параметр:
Теперь, когда вы можете принять интерфейс вашего объекта уровня бизнес / данных, вы можете смоделировать его во время модульных тестов и не иметь никаких зависимостей или боязни "случайного" интеграционного тестирования.
Таким образом, в вашем живом коде вы передаете
IBusinessDataEtc
объект REAL . Но в вашем модульном тестировании вы передаетеIBusinessDataEtc
объект MOCK . В этом макете вы можете включить неинтерфейсные свойства, такие какint XMethodWasCalledCount
или что-то, чьи состояния обновляются при вызове методов интерфейса.Таким образом, ваш модульный тест пройдет ваш метод (ы) в вопросе, выполнит любую логику и вызовет один или два или выбранный набор методов в вашем
IBusinessDataEtc
объекте. Когда вы делаете свои утверждения в конце вашего модульного теста, у вас есть несколько вещей, чтобы проверить сейчас.IBusinessDataEtc
объекта.Для получения дополнительной информации об идеях внедрения зависимостей на уровне конструкции ... как они относятся к модульному тестированию ... посмотрите шаблоны проектирования Builder. Он добавляет еще один интерфейс и класс для каждого текущего интерфейса / класса, который у вас есть, но они очень маленькие и обеспечивают ОГРОМНОЕ увеличение функциональности для лучшего модульного тестирования.
источник
public void sendEmailToCustomer() throws UndeliveredMailException
?void
методах, особенно в объектно-ориентированных языках, это был единственный реальный вариант. Самая старая альтернатива от Microsoft - это парадигма Try-Paradigm, которую я обсуждаю, и парадигмы функционального стиля, такие как Monads / Maybes. Таким образом, Команды (в CQS) могут по-прежнему возвращать ценную информацию о состоянии вместо того, чтобы полагаться на бросок, который похож наGOTO
(что, как мы знаем, плохо). броски (и переходы) медленны, трудны для отладки и не являются хорошей практикой.Попробуй это:
источник
ExpectedAttribute
сделано для того, чтобы сделать этот тест более четким.Вы даже можете попробовать это так:
источник
это будет иметь некоторый эффект на объект .... запрос на результат эффекта. Если он не имеет видимого эффекта, его не стоит тестировать!
источник
Предположительно метод что-то делает, а не просто возвращает?
Если предположить, что это так, то:
Если вы дадите нам знать, что делает метод, я мог бы быть более конкретным.
источник
Используйте Rhino Mocks для установки ожидаемых вызовов, действий и исключений. Предполагая, что вы можете смоделировать или заглушить части вашего метода. Трудно понять, не зная здесь некоторых подробностей о методе или даже контексте.
источник
Зависит от того, что он делает. Если у него есть параметры, передайте макеты, которые вы могли бы спросить позже, были ли они вызваны с правильным набором параметров.
источник
Какой бы экземпляр вы ни использовали для вызова метода void, вы можете просто использовать,
Verfiy
Например:
В моем случае
_Log
это экземпляр иLogMessage
тестируемый метод:Является ли
Verify
выбросы исключением из-за сбоя метода, который провалился бы при тестировании?источник