Как стать автором
Обновить

Комментарии 9

Привет, привет!

Несколько философский вопрос: а нам точно нужны такие подробности как был ли вызван имя_метода? Не совсем понятно, что нам это гарантирует. То что он вызвался не значит что все правильно?

А еще мне кажется что в данном случаем мы тестирует «техническую» реализацию составляющую, а не «логическую». Что я имею ввиду, мы проверяем не «правильность» работы а «путь» выполнения работы. На простом примере, мы должны валидировать имейл. Вместо того чтоб, проверять конечный результат валидный/невалидный, мы проверяем как мы это делаем(регялярки или еще что-то).
Несколько философский вопрос: а нам точно нужны такие подробности как был ли вызван имя_метода? Не совсем понятно, что нам это гарантирует. То что он вызвался не значит что все правильно?


В случае с Interactor'ом, мы проверяем, было ли обращение к Presenter'у и Worker'у.
— Вызывается Presenter, значит нет запутанной (тупиковой) логики в методе Interactor'a и данные уходят дальше.
— В случае с Worker'ом, мы подставляем тестовый дубль (Spy) для избежания реальных запросов в сеть при тестировании. Так же возвращаем шаблонные данные (вместо реальных из сети), для удобства тестирования работы логики Interactor'a. Так же, без подмены Worker'a, не будет вызываться замыкание, а значит мы не обработаем данные и не передадим их в Presenter. Но это уже от кейсов зависит.

А еще мне кажется что в данном случаем мы тестирует «техническую» реализацию составляющую, а не «логическую». Что я имею ввиду, мы проверяем не «правильность» работы а «путь» выполнения работы. На простом примере, мы должны валидировать имейл. Вместо того чтоб, проверять конечный результат валидный/невалидный, мы проверяем как мы это делаем(регялярки или еще что-то).


Да, конечно, мы должны проверять результат. Основная задача статьи — показать как это делается с компонентами в Clean Swift, как заменять объекты тестовыми дублями, для чего и к чему это приводит. В полном примере приложения (на GitHub), есть тестирование Presenter'a, где проверяется правильность сортировки и т.д.
Благодарю за ответ! Я более детально ознакомился с проектом и у меня возникли ряд вопросов. Буду рад дискусии.

Вопрос. Проект CleanSwiftTests
В компоненте «Home» есть «HomeWorker» — фактически это класс отвечающий за запрос на сервер. Мне нравиться что под один endpoint есть отдельный класс. Но мне не понравилось, что этот класс является частью компонента «Home». А если он мне понадобится в другом компоненте? Я тоже буду использовать его? Но тогда это будет зависимостью между двумя модулями/компонентами.
Класс HomeWorker содержит в себе методы только для сцены Home, не обязательно запросы в сеть. На «реальных проектах», запросы в сеть строятся в отдельном Network слое, а Worker'ы используются для «выноса» сложной/объемной реализации из Interactor'a для его разгрузки.

А если он мне понадобится в другом компоненте? Я тоже буду использовать его? Но тогда это будет зависимостью между двумя модулями/компонентами.


Нет, такой зависимости не должно быть. Для этого делаются глобальные Worker'ы и размещаются в директории Workers для переиспользования в разных сценах (в проекте CleanSwiftTests такой файл есть).

Как пример:
Вы имеете слой Network, который содержит в себе модели, ендпоинты и все необходимое, чтоб отправлять запросы и парсить ответы в модели. Далее, уже на Presentation слое (где у нас Clean Swift), мы через глобальные Worker'ы (если требуется использование на разных сценах) или локальные (если это только для одной сцены) выстраивает запрос (напрямую, если отсутствует отдельный слой Business Logic), обрабатываем его и возвращаем в Interactor через замыкание (или иный способ). Но это в том случае, если запрос нужно объемным способом сформировать или объемным способом обработать ответ. В противном случае, можно обращаться напрямую из Interactor'a (к Network или Business слою).
Понятно. Я во многом согласен с Вашим взглядом на эту проблему. Но считаю очень важным подчеркнуть то что Вы сказали, что Clean Swift (в нашем контексте) — это архитектура на уровне отображения, а не на уровне всего приложения. Считаю что это очень важно и это стоит упомянуть в первой главе, так как на данный момент создается впечатление. что мы все приложение должны делать в таких модулях(компонентах) VIP.

Я все время вижу как все пытаются делать приложения отталкиваясь от отображения(дизайна) а не юзкейсов. Этим страдают многие «архитектуры» VIPER, MVVM и тд. Это все архитектуры реализации UI а не приложения вцелом.
Так и есть. Мое упущение, что не сделал должного акцента на том, что Clean Swift архитектура презентационного слоя. Впереди еще одна статья (на самом деле две), где сделаю должный акцент на этом моменте. Спасибо.
Спасибо за статью!
Хочу дополнить, что вместо свойств типа isCalledFetchUsers можно использовать enum Action, который дублирует название функций или их смысл. И в каждой функции добавлять значение в общий массив — actions. Так мы сможем проверять еще порядок вызова функций и количество вызовов.

Понимаю, что статье уже больше года, но доступа к проектам нет на GitHub.
Есть новые ссылки или прмеры канули в Лету?

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории