Вы делаете вывод о нужности юнит-тестов, руководствуясь частным случаем и основываясь на последствиях. Конечно, практика вносит свои корректировки: непрофессионализм девелоперов, ошибки проектирования и пр., которые следует учитывать. Но то кол-во случаев на каждом IF или SWITСH, которое можно проверить unit-tests вы никогда не проверите интеграционными. Либо это превратится в такой головняк с интеграционными, когда написание тестов жрет не меньше временеи, чем сам функционал.
То о чем вы говорите стандартные заблуждения. Если бы были интеграционные тесты, то ошибки были бы замечены. Но какой-то человек решил их не делать. А вывод, почему-то, делается не о его профессионализме, а о ненужности unit-test, которые свою работу сделали на отлично, как мне кажется. Как долго вы искали проблему?
G>Вот у тебя есть метод — делает выборку, обрабатывает, сохраняет. Это твой сценарий. G>Для теста ты репозиторий подменяешь банальной реализацией на list<t>, когда метод просто отдает список. И проверяешь что данные в списке поменялись. G>Ты написал код, который делает обработку, а SaveChangesAsync забыл. Тест проходит. При запуске не работает, тупо ничего не происходит.
Я бы распилил на несколько методов, которые по-отдельности можно протестировать. Т.е. выборка проверялась бы интеграционным тестом, обработка — юнит тестом, сохранение — интеграционным. При этом в юнит тесте выборку и сохранение я бы замокал. Выборка и сохранение на локальной базе — дело быстрое и не требующее кучи предварительных настроек данных.
G>У тебя два варианта: G>1) Делать реальный транзакционный inmemory storage. Но я таких не видел за 10 лет (слава богу в EFCore его сделали).
Сделать можно, но не надо.
G>2) Проверять integration-тестом, но с ними проблем еще больше — медленно, тестовые данные нужны, писать тесты сложнее.
Корень проблемы не в интеграционных тестах, а в людях, которые не умеют их писать. Как обычно, впрочем. Скорее всего, описанные тесты у вас больше похожи на end-to-end тесты, когда вы запускаете целиков всё (ВСЁ). Такие действильно очень тяжелые во всех отношениях. Тут необходимо помнить, что задача тестов (любых): проверить работу известного сценария. Приэтом, юнит — алгоритмы проверяет, а интеграционный только связку. Если перемешивать, то возникают проблемы.
G>На практике получается еще хуже. G>У меня был случай, когда программа уже была написана и покрыта юнит-тестами. Покрытие методов БЛ было 100%. И тут провели рефакторинг, в процессе случайно выпилили SaveChanges в нескольких методах. Ничего не упало, ни тесты, ни код, но приложение перестало работать. Интеграционных тестов не было ибо юнит тесты покрывают 100% и так.
G>После этого я бросил писать юнит-тесты для бизнес-приложений. Интеграционные тесты делаю если руками проверять дольше. Поэтому отпала потребность подменять хранилище, и стал не нужен паттерн repository.
Сколько людей на проекте?? Один-два?.. Риторический вопрос.