Модульное тестирование Android с помощью AsyncTask и UI Updates Solution

Сценарий:

Я пытаюсь выполнить модульное тестирование обработчика onClick своего приложения. Onclick выполняет простой поиск по API REST, возвращает результаты и обновляет пользовательский интерфейс.

Подробности:

Onclick выполняет AsyncTask, doInBackground запрашивает REST API и возвращает результаты. OnPostExecute берет результаты и назначает новый ListAdapter для ListView с данными.

Проблема:

OnPostExecute не вызывается исполнителем теста, поскольку он находится в том же потоке пользовательского интерфейса и блокирует вызов. Есть несколько способов борьбы с этим. Однако, если я помещаю AsyncTask в Runnable и использую LatchCountdown для ожидания результата, я получаю исключение CalledFromWrongThread.

Есть хорошее решение для модульного тестирования AsyncTask, который обновляет пользовательский интерфейс? Или более тестируемый дизайн, который я могу реализовать?

2 ответа

Решение

Итак, решение, которое я придумал, заключается в следующем:

1.) Определите интерфейс слушателя для событий до и после.
2.) Внедрить слушателя в Activity
2.) Определите класс-оболочку для задачи, который принимает прослушиватель и у которого есть внутренняя AsyncTask, которая вызывается в exec.
3.) Внутренний AsyncTask уведомляет слушателя о onPreExecute и onPostExecute
4.) После уведомления Активность обновляет свой интерфейс.

Для тестирования в Деятельности:
1.) Создайте последовательную версию класса-оболочки, унаследовав от него, затем переопределив метод exec для выполнения в последовательности:
- уведомить слушателя о том, что задание началось.
- выполнить задание.
- уведомить слушателя, что задание выполнено.

Для тестирования Асинхронной версии задачи.
1.) Используйте CountdownLatch и Runnable в методе модульного тестирования. Поскольку не требуется никаких обновлений пользовательского интерфейса, у вас не будет никаких исключений WrongThreadException.

Вы хотите запустить тест в потоке пользовательского интерфейса

runOnUiThread(new Runnable() {
   public void run() {
      onPostExecute(...)

  }
});
Другие вопросы по тегам