Модульное тестирование 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(...)
}
});