Что-либо, что не абсолютно детерминировано, нет - нет для поблочного тестирования. Вы хотите, чтобы Ваши модульные тесты ВСЕГДА передали или перестали работать с теми же начальными условиями - если странность как поточная обработка или случайное поколение данных, или время/даты или внешние сервисы может влиять на это, то Вы не должны покрывать его в своих модульных тестах. Время/даты является особенно противным случаем. Можно обычно проектировать код для имения даты для работы с быть введенными (кодом и тестами) вместо того, чтобы полагаться на функциональность в текущей дате и время.
, Который сказал, хотя, модульные тесты не должны только находиться на одном уровне тестирования в Вашем приложении. Достижение 100%-го покрытия модульного теста часто является пустой тратой времени, и быстро встречает убывающую доходность.
Намного лучше должен иметь ряд высокоуровневых функциональных испытаний и даже интеграционных тестов, чтобы гарантировать, что система работает правильно , "как только это все соединено" - который модульные тесты по определению не делают тест.
Это все отличные сообщения. Пока я больше всего согласен с Брайаном Расмуссеном - создавайте собственные исключения, когда вы хотите обрабатывать различные типы конкретных исключений.
Возможно, поможет пример. Это надуманный пример, и он может быть полезен или бесполезен в повседневном коде. Предположим, у вас есть класс, отвечающий за аутентификацию пользователя. Этот класс, помимо аутентификации пользователя, имеет механизм блокировки для блокировки пользователя после нескольких неудачных попыток. В таком случае вы можете разработать как часть класса два настраиваемых исключения: AuthenticationFailedException
и UserLockedOutException
. Ваш метод AuthenticateUser
затем просто вернется без выброса, если пользователь был успешно аутентифицирован, выбросить AuthenticationFailedException
, если пользователь не прошел аутентификацию, или выбросить UserLockedOutException
, если пользователь был заблокирован.
Например:
try
{
myAuthProvider.AuthenticateUser(username, password);
ShowAuthSuccessScreen();
}
catch(AuthenticationFailedException e)
{
LogError(e);
ShowAuthFailedScreen();
}
catch(UserLockedOutException e)
{
LogError(e);
ShowUserLockedOutScreen();
}
catch(Exception e)
{
LogError(e);
ShowGeneralErrorScreen();
}
Опять надуманный пример. Но, надеюсь, он покажет, как и почему вы хотите создавать собственные исключения. В этом случае пользователь класса AuthProvider
обрабатывает каждое настраиваемое исключение по-разному. Если бы метод AuthenticateUser
просто сгенерировал Exception
, не было бы возможности различать разные причины , по которым было создано исключение.
AuthProvider
обрабатывает каждое настраиваемое исключение по-разному. Если бы метод AuthenticateUser
просто выдал Exception
, не было бы никакого способа различить разные причины , по которым было создано исключение. пользователь класса AuthProvider
обрабатывает каждое настраиваемое исключение по-разному. Если бы метод AuthenticateUser
просто сгенерировал Exception
, не было бы возможности различать разные причины , по которым было создано исключение. Зачем создавать собственные исключения?
За / против использования исключений см. Как создать хорошее исключение
Факторы, которые следует учитывать при использовании пользовательских исключений
Рекомендации для создания настраиваемых исключений
Создание и выброс исключений
На самом деле существует большая серия статей MSDN по этой теме:
Пользовательские исключения позволяют вам предоставлять четкие, значимые исключения, которые, в свою очередь, могут сделать вашу библиотеку более удобной, при условии, что вы используете существующие исключения, когда это необходимо.
Создавайте настраиваемое исключение каждый раз, когда вы необходимо вызвать исключение, которое не вписывается непосредственно в модель исключений фреймворка.
Недавно я написал целую запись в блоге на эту конкретную тему:
Основное резюме:
Вы должны создавать новое исключение только в том случае, если вы ожидаете, что разработчики предпримут действия по исправлению проблемы или войдут в журнал для посмертной отладки.
Используйте собственные исключения, чтобы отмечать ошибки, специфичные для вашего приложения / домена. Преимущество состоит в том, что ваши блоки catch могут фильтровать правильные исключения и действовать в соответствии с ними. Для всего остального используйте определенные стандартные исключения.