Поскольку я не очень опытен в модульном тестировании, я пытаюсь собрать некоторые правила, которые я изучу в первую очередь.
Внимательно изучайте «правила» для проблем, с которыми вы никогда не сталкивались. Если вы сталкиваетесь с каким-то «правилом» или «наилучшей практикой», я бы предложил найти простой игрушечный пример того, как «правило» следует использовать, и попытаться решить эту проблему самостоятельно , игнорируя то, что говорит «правило».
В этом случае вы можете попытаться создать 2 или 3 простых класса и некоторые варианты поведения, которые они должны реализовать. Реализуйте классы любым удобным для вас способом и напишите модульный тест для каждого поведения. Составьте список всех проблем, с которыми вы столкнулись, например, если вы начали с того, что все работает в одну сторону, то вам нужно было вернуться и изменить это позже; если вы запутались в том, как вещи должны соответствовать друг другу; если вас раздражает написание шаблона; и т.п.
Затем попробуйте решить ту же проблему, следуя «правилу». Опять же, составьте список проблем, с которыми вы столкнулись. Сравните списки и подумайте, какие ситуации могут быть лучше при соблюдении правила, а какие нет.
Что касается вашего реального вопроса, я склоняюсь к подходу портов и адаптеров , где мы проводим различие между «базовой логикой» и «услугами» (это похоже на различие между чистыми функциями и эффективными процедурами).
Основная логика заключается в том, чтобы вычислять вещи «внутри» приложения на основе проблемной области. Он может содержать классы , как User, Document, Order, Invoice, штраф и т.д. Это иметь базовые классы называть newдля других основных классов, так как они «внутренней» детали реализации. Например, создание Orderможет также создать Invoiceи Documentдетализацию того, что было заказано. Во время тестов нет нужды насмехаться над этим, потому что это именно то, что мы хотим протестировать!
Порты и адаптеры - это то, как ядро логики взаимодействует с внешним миром. Это где вещи , как Database, ConfigFile, EmailSenderи т.д. жить. Это то, что усложняет тестирование, поэтому желательно создавать их вне базовой логики и передавать их по мере необходимости (либо с помощью внедрения зависимости, либо в качестве аргументов метода и т. Д.).
Таким образом, основная логика (которая является частью конкретного приложения, где важна бизнес-логика и подвержена наибольшему оттоку) может быть проверена сама по себе, без необходимости заботиться о базах данных, файлах, электронных письмах и т. Д. Мы можем просто передать некоторые примерные значения и проверить, что получаем правильные выходные значения.
Порты и адаптеры можно тестировать отдельно, используя макеты для базы данных, файловой системы и т. Д., Не заботясь о бизнес-логике. Мы можем просто передать некоторые примеры значений и убедиться, что они хранятся / читаются / отправляются / и т.д. соответственно.