Использование обратного вызова, например. от Interactor к Presenter, может затруднить тестирование Presenter.
При написании тестов для того, как Presenter обрабатывает входные данные (отправленные из Interactor), ваш тест должен будет вызывать некоторый метод в Presenter, который заставит Presenter сделать вызов Interactor, что заставит Interactor отправить данные в Presenter. .
Если Presenter реализует протокол, определенный Interactor, ваш тест может просто напрямую вызвать соответствующий метод ввода в Presenter.
Что касается объявления протоколов, то я практикую TDD в стиле фиктивных ролей, а не объектов (http://www.jmock.org/oopsla2004.pdf). Протоколы помогают обеспечить лучшую абстракцию, сосредотачиваясь на том, что делает объект (его роль), а не на том, как он это делает.
Протоколы сами по себе не имеют большого значения для модульных тестов. Ваши модульные тесты будут предоставлять тестовые двойники (http://martinfowler.com/bliki/TestDouble.html) для зависимостей тестируемой системы. Даже если вы предоставляете зависимости как конкретные классы, вы все равно можете создавать тестовые двойники для своего теста.
В Objective-C можно использовать имитирующую библиотеку, например OCMock (http://ocmock.org), или OCMockito (https://github.com/jonreid/OCMockito), для создания заглушек, шпионов или макеты конкретного класса.
В Swift вы можете создавать свои тестовые двойники, создавая подклассы для каждого из конкретных классов, используемых в качестве зависимостей.
Короче говоря, протоколы используются не для облегчения модульного тестирования, а для описания на более высоком уровне абстракции того, что делает приложение.
Вот пример того, как абстрактные протоколы были полезны постфактум:
Я создал протокол для представления действий, которые пользователь может выполнять на экране, например. ProfileUserActions
с такими действиями, как changeName
и changeAddress
. Презентатор реализовал ProfileUserActions
, а представление приняло ProfileUserActions
в качестве зависимости. Когда пользователь нажимал кнопку на экране, представление отправляло соответствующее сообщение своему объекту userActions
.
Когда я захотел добавить аналитику, я смог создать новый независимый класс ProfileAnalytics
, который также реализовал ProfileUserActions
. Я вставил объект аналитики между представлением и презентатором, что позволило приложению собирать аналитику без необходимости изменять представление или презентатор.
person
Jeff Gilbert
schedule
18.12.2016