Тестирование издателя стало проще
После использования ReactiveCocoa, RxSwift в течение некоторого времени у меня появилась возможность перейти на фреймворк Apple Combine. Конечно, теперь мне нужно было провести модульное тестирование всех этих издателей.
Работа с потоками дает большие преимущества, такие как более чистый код, меньшее количество побочных эффектов, меньшие классы. Но у него есть и один недостаток, тестирование немного сложнее.
Что я сделал, так это то, что я попытался немного упростить тестирование.
Проблема
Представим, что у нас есть протокол Device
, который возвращает текущее состояние устройства.
protocol IDevice { func deviceState() -> String }
Кроме того, у нас есть UseCase
, где мы хотим получить логическое значение, если устройство включено или выключено в соответствии с его состоянием. Без Combine наш код выглядел бы так:
В нашем модульном тесте нам понадобится IDevice-Mock
, где мы имитируем deviceState()
, чтобы мы могли протестировать каждый случай.
Опубликованный подход
Теперь, с помощью Combine, мы изменим функции, сделав их более «реактивными». Итак, мы заменили возвращаемые значения на Publishers.
Тестирование стало непростым делом. Нам нужно будет подписаться на isOn()
и поиздеваться над deviceState()
. Итак, давайте сделаем это.
Теперь мы создали массив expectedValues
, в котором перечисляем значения, которые мы ожидаем от Publisher<Bool>
,, на которые мы подписались, сохранили значения, которые были отправлены в приемник, а затем отправили состояния устройства с помощью deviceStateSub
.
Конечно, это не сработает, если выходные данные Издателя не равноценны.
Итак, что я сделал, я написал несколько вспомогательных функций, которые упростят мне жизнь.
Решение
Во-первых, вспомогательной функцией будет expectCompletion
, и мы используем ее, чтобы проверить, завершается ли Observable.
Вспомогательная функция вернет ожидание. Затем нам нужно просто отправить завершение из макета и дождаться ожидания.
Теперь мы добавляем вспомогательную функцию expectValue
к нашему расширению, которая будет проверять равные значения:
В параметре equals
функции expectValue
мы даем значения, которые ожидаем от .isOn()
Издателя. После этого мы отправляем значения из нашей темы deviceStateSub
.
Итак, мы ожидаем, что когда deviceState равно Off
, isOn()
вернет false
, если On
, он должен вернуть true
.
Наконец, у нас есть аналогичная функция для обработки более сложных проверок. Представьте, что в нашем IsOnUseCase
есть еще одна функция, которая возвращает не равноправный пользовательский объект с текстом.
Наша тестовая функция expectValue
, также принимает список закрытий .
Теперь нам нужно будет использовать замыкания, чтобы проверить результат isOn()
Publisher.
Надеюсь, вы нашли вышеуказанные функции полезными.
Удачного модульного тестирования.