ActivityUnitTestCase и Activity # runOnUiThread - PullRequest
6 голосов
/ 14 марта 2012

Мой тест сфокусирован на AsyncTask, завершающем и проверяющем, что запущено последующее действие.

Известно, что AsyncTask # onPostExecute не вызывается, если не создан экземпляр AsyncTask и не выполнен из потока пользовательского интерфейса, поэтому мой метод (test visible) для вызова AsyncTask проходит необходимые меры предосторожности для обеспечения такого поведения - через Runnable, который немедленно запускается, если в потоке пользовательского интерфейса, или запланирован запуск в потоке пользовательского интерфейса.

Когда этот метод вызывается из теста ActivityUnitTestCase, Runnable, который создает и выполняет этот AsyncTask через Activity # runOnUiThread, заканчивается выполнением в потоке, отличном от потока пользовательского интерфейса. Есть ли способ гарантировать, что этот Runnable будет выполняться в потоке пользовательского интерфейса из Activity?

Addenda:

  • Тест выполняется в соответствии с ожиданиями в ActivityInstrumentationTestCase2 класс, но у меня нет доступа к ActivityUnitTestCase # getStartedActivityIntent. Я в курсе Instrumentation.ActivityMonitor и это не решение.
  • Запланированные Runnables в ActivityUnitTestCase # runTestOnUiThread do запуск в пользовательском интерфейсе нить.
  • Я не собираюсь переопределять свой тест.
  • Как ни странно, ActivityUnitTestCase # startActivity вызывает Activity # onCreate NOT в потоке пользовательского интерфейса.

Редактировать: Вот небольшой (не проверенный) код, который демонстрирует суть проблемы:

// ExampleActivityTests.java

class ExampleActivityTests : public ActivityUnitTestCase <ExampleActivity> {

    public void testThatRequiresUiThread() {

        startActivity (new Intent(), null, null);
        // ...call instrumentation onStart, onResume...

        runTestOnUiThread(new Runnable() {
            public void run() {
                boolean isUiThread = Thread.currentThread() == Looper.getMainLooper().getThread();
                Log.d ("A", "Running on UI Thread? " + isUiThread);
            }
        });

        getActivity().methodRequiringUiThread();

        // assertions here...
    }
}

// ExampleActivity.java -- just the relevant method

    public void methodRequiringUiThread() {

        runOnUiThread(new Runnable() {
            public void run() {
                boolean isUiThread = Thread.currentThread() == Looper.getMainLooper().getThread();
                Log.d ("B", "Running on UI Thread? " + isUiThread);
            }
         });
    }

В LogCat мы увидим:

A | Running on UI Thread? true
B | Running on UI Thread? false

1 Ответ

4 голосов
/ 14 марта 2012

Вызов ActivityUnitTestCase # startActivity в потоке пользовательского интерфейса решает мою проблему.

public void testThatRequiresUiThread() {

    runTestOnUiThread(new Runnable() {

        @Override
        public void run() {
            startActivity(new Intent(), null, null);
        }
    });

    // ...
    getActivity().methodRequiringUiThread();

    // rest of test...
}

выходы

A | Running on UI Thread? true
B | Running on UI Thread? true
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...