Comments 2
Я для себя давно вывел простое правило: юнит-тесты нужны там, где есть сложная логика. Если есть больше одного места, где можно допустить ошибку на единицу, сложные RegExp'ы - там нужны юнит-тесты.
Для того, чтобы всё это не превратилось в ад хрупких тестов "мок на моке сидит и моками погоняет" мы стараемся выносить эту сложную логику в функциональное ядро. И то, что мы пишем не на функциональном языке (C#) не мешает нам это функциональное ядро находить и выделять.
Тут важно вывести из требований относительно стабильный контракт и его тестировать. Может оказаться, что логика сценария для этого контракта сложна, кейсов проверки слишком много, тогда приходится спускаться на уровень ниже, но в целом, как показала практика, найденное ядро остаётся стабильным и не мешает рефакторингу.
В результате у нас много статических функций (проклятых ООП-евангилистами), данные на входе, данные на выходе, как правило, никаких моков, и тесты - простые как палки.
>Недостаток 2. Ничего не тестируют
Это из книг берётся. В стародавние времена читал что-то типа "Unit-тест в .NET" и один из первых примеров - тестирование метода класса с двумя зависимостыми. Сам метод из двух строк - берёт по Id данные из одной зависимости и вызывает метод другой зависимости с полученными данными. И листинги моков на целый разворот, чтобы это проверить. Становится непонятно, что тут тестируется - поведение классов или правильность написания моков.
Хуже всего, что и в продуктовой разработке с этим подходом регулярно приходится сталкиваться.
P.S. Вообще, у Владимира Хорикова в книге "Принципы юнит-тестирования" эти моменты про устойчивость тестов к рефакторингу очень хорошо освещены.
Гайд по автотестам, часть 2. Юнит-тесты