-
Научиться использовать потокобезопасные компоненты из корутин.
-
Покрыть юнит-тестами бизнес-логику.
-
Реализовать обработку ошибок и добавить логику перезапроса при возникновении ошибки.
-
Склонировать проект отсюда - https://github.com/yandex-praktikum/middle-android-repo2 .
-
Выполнить задания поочерёдно.
Вам требуется последовательно выполнить задания проекта, чтобы прийти от старта к финишу - где-то нужно будет отрефакторить уже существующий код, где-то написать новый с нуля, либо раскомментировать нужный фрагмент.
Поехали!
Для начала потребуется заменить использование LiveData
на StateFlow
для оптимизации работы с данными
Сейчас LiveData
находится внутри ChatViewModel
. Для перевода на StateFlow
требуются следующие шаги:
- Создать
StateFlow<List<String>>
вChatViewModel
и удалить использованиеLiveData
.
private val _messages = MutableStateFlow(emptyList<Message>())
private val messages = _messages.asStateFlow()
- Переписать метод
sendMessage(String)
, только теперь с использованием ранее созданногоFlow
.
suspend fun sendMyMessage(text: String) {
_messages.update {
// логика добавления нового сообщения в _messages
}
}
- Внутри MainActivity заменить
observeAsState
наcollectAsState
дляmessages
.
В этом задании нужно написать unit-тест на ChatViewModel
.
Откройте файл ChatViewModelTest
. В нём уже содержатся необходимые приготовления — мокирование,
а также два метода для тестов. В этом задании вам нужно работать с методом send message should update messages with MyMessage
. Внутри него вам нужно написать тест и проверить, что при вызове метода &sendMyMessage()
в переменной messages
внутри ViewModel
будет содержаться отправленное сообщение.
Также нужно раскоментировать Dispatchers.setMain
и Dispatchers.resetMain
, так как требуется подменить диспатчер,
который используется внутри ViewModel
, на тестовый.
В данном задании вы напишите юнит-тест, который проверит потокобезопасность нашей реализации.
Внутри метода testReceiveMessage_concurrentMessages
напишите тест по аналогии с тестом из задания 2, но который будет одновременно отправлять 100 сообщений из списка messagesToSend
.
{% cut "Подсказка" %}
Вам нужно запустить несколько корутин одновременно. Как это сделать?
Создать coroutineScope
и для каждого сообщения сделать fire-and-forget корутину. Этого можно добиться через билдер launch
также мы должны дождаться окончания их выполнения. Здесь пригодится использование extenstion-функции Collection<Job>.joinAll
для параллельного запуска сразу 100 добавлений в список сообщений.
Далее мы должны проверить количество сообщений и их содержание.
{% endcut %}
В этом задании вам необходимо написать логику обработки ошибок «сети». Конечно, настоящих запросов в сеть в проекте нет, и ошибки с будут эмулироваться в ChatApi
.
-
Раскомментируйте строчку со случайным бросанием ошибки в
ChatApi
. Судя по коду, запрос за ответным сообщением будет возвращаться с ошибкой с заметной регулярностью. -
Добавьте обработчик в метод
getReplyMessage()
из классаChatRepository
, который будет повторять запрос несколько раз с экспоненциальным увеличением тайм-аута. Для этого пригодится функцияretryWhen
, в которой вы должны написать условие на проверку ошибке и в этом случае вызыватьdelay
с заданным временем задержки, после которого увеличивать время задержки.Пример кода для реализации:
if (exception != null) { delay(currentDelay) currentDelay *= DELAY_FACTOR }
-
Чтобы быть уверенным в надёжности данной логики, напишите юнит-тесты, которые будут проверять обработку ошибки и успешное получение.
В файле
ChatRepositoryTest
есть два метода — один для проверки успешного ответа, другой для проверки ретрая. Код для проверки ретрая уже написан — так вы можете проверить, что логика реализованная вами в репозитории, работает правильно. Напишите по аналогии тест для проверки успешного ответа без ретрая&.
-
Приложение переведено с использования
LiveData
наFlow
. -
Реализована потокобезопасная работа со списком сообщений — все сообщения приходят согласно порядку их отправки, с использованием потокобезопасных типов и функций, отсутствует состояние гонки.
-
Логика внутри
ViewModel
покрыта юнит-тестами. -
Реализован механизм обработки ошибок, добавлена логика экспоненциального ретрая, а также написаны юнит-тесты на эту логику.