Skip to content

Foxxx48/middle-android-repo2

 
 

Repository files navigation

Цели практической работы

  • Научиться использовать потокобезопасные компоненты из корутин.

  • Покрыть юнит-тестами бизнес-логику.

  • Реализовать обработку ошибок и добавить логику перезапроса при возникновении ошибки.

Что нужно сделать

Как работать с проектом

Вам требуется последовательно выполнить задания проекта, чтобы прийти от старта к финишу - где-то нужно будет отрефакторить уже существующий код, где-то написать новый с нуля, либо раскомментировать нужный фрагмент.

Поехали!

Задание 1

Для начала потребуется заменить использование LiveData на StateFlow для оптимизации работы с данными

Сейчас LiveData находится внутри ChatViewModel. Для перевода на StateFlow требуются следующие шаги:

  1. Создать StateFlow<List<String>> в ChatViewModel и удалить использование LiveData.
private val _messages = MutableStateFlow(emptyList<Message>())
private val messages = _messages.asStateFlow()
  1. Переписать метод sendMessage(String), только теперь с использованием ранее созданного Flow.
suspend fun sendMyMessage(text: String) {
        _messages.update {
            // логика добавления нового сообщения в _messages
        }
}
  1. Внутри MainActivity заменить observeAsState на collectAsState для messages.

Задание 2

В этом задании нужно написать unit-тест на ChatViewModel.

Откройте файл ChatViewModelTest. В нём уже содержатся необходимые приготовления — мокирование, а также два метода для тестов. В этом задании вам нужно работать с методом send message should update messages with MyMessage. Внутри него вам нужно написать тест и проверить, что при вызове метода &sendMyMessage()в переменной messages внутри ViewModel будет содержаться отправленное сообщение.

Также нужно раскоментировать Dispatchers.setMain и Dispatchers.resetMain, так как требуется подменить диспатчер, который используется внутри ViewModel, на тестовый.

Задание 3

В данном задании вы напишите юнит-тест, который проверит потокобезопасность нашей реализации.

Внутри метода testReceiveMessage_concurrentMessages напишите тест по аналогии с тестом из задания 2, но который будет одновременно отправлять 100 сообщений из списка messagesToSend.

{% cut "Подсказка" %}

Вам нужно запустить несколько корутин одновременно. Как это сделать?

Создать coroutineScope и для каждого сообщения сделать fire-and-forget корутину. Этого можно добиться через билдер launch также мы должны дождаться окончания их выполнения. Здесь пригодится использование extenstion-функции Collection<Job>.joinAll для параллельного запуска сразу 100 добавлений в список сообщений.

Далее мы должны проверить количество сообщений и их содержание.

{% endcut %}

Задание 4

В этом задании вам необходимо написать логику обработки ошибок «сети». Конечно, настоящих запросов в сеть в проекте нет, и ошибки с будут эмулироваться в ChatApi.

  1. Раскомментируйте строчку со случайным бросанием ошибки в ChatApi. Судя по коду, запрос за ответным сообщением будет возвращаться с ошибкой с заметной регулярностью.

  2. Добавьте обработчик в метод getReplyMessage() из класса ChatRepository, который будет повторять запрос несколько раз с экспоненциальным увеличением тайм-аута. Для этого пригодится функция retryWhen, в которой вы должны написать условие на проверку ошибке и в этом случае вызывать delay с заданным временем задержки, после которого увеличивать время задержки.

    Пример кода для реализации:

    if (exception != null) {
        delay(currentDelay)
        currentDelay *= DELAY_FACTOR
    }
  3. Чтобы быть уверенным в надёжности данной логики, напишите юнит-тесты, которые будут проверять обработку ошибки и успешное получение.

    В файле ChatRepositoryTest есть два метода — один для проверки успешного ответа, другой для проверки ретрая. Код для проверки ретрая уже написан — так вы можете проверить, что логика реализованная вами в репозитории, работает правильно. Напишите по аналогии тест для проверки успешного ответа без ретрая&.

Что должно получиться в итоге

  • Приложение переведено с использования LiveData на Flow.

  • Реализована потокобезопасная работа со списком сообщений — все сообщения приходят согласно порядку их отправки, с использованием потокобезопасных типов и функций, отсутствует состояние гонки.

  • Логика внутри ViewModel покрыта юнит-тестами.

  • Реализован механизм обработки ошибок, добавлена логика экспоненциального ретрая, а также написаны юнит-тесты на эту логику.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Kotlin 100.0%