2012-03-14 118 views
6

我的測試着重於一個AsyncTask完成並驗證後續活動已啓動。ActivityUnitTestCase和Activity#runOnUiThread

已知AsyncTask#onPostExecute不會被調用,除非AsyncTask被實例化並從UI線程執行,所以調用AsyncTask的我的(測試可見)方法需要通過必要的預防措施來確保這種行爲 - 通過Runnable如果在UI線程上或者計劃在UI線程上運行,則會立即運行。

當從ActivityUnitTestCase測試中調用此方法時,通過Activity#runOnUiThread實例化並執行此AsyncTask的Runnable最終在UI線程以外的線程上運行。 有沒有辦法確保這個Runnable將在Activity的UI線程上執行?

附錄:

  • 試運行下ActivityInstrumentationTestCase2 類如希望的那樣,但我沒有訪問 ActivityUnitTestCase#getStartedActivityIntent。我知道 Instrumentation.ActivityMonitor,這是一個非解決方案。
  • 在ActivityUnitTestCase上計劃的Runnables#runTestOnUiThread do在UI 線程上運行。
  • 我不想重新定義我的測試。
  • 奇怪的是,ActivityUnitTestCase#startActivity調用Activity#onCreate而不是在UI線程上。

編輯:這是一個位的(未經測試)的代碼,演示了問題的實質:

// 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

通過閱讀您的語句_弄得有點「通過一個Runnable立即運行,如果在UI線程或計劃在UI線程上運行」 _,更好地附着一些代碼片段來澄清你的問題。 – yorkw 2012-03-14 00:37:00

+0

也許這個陳述太詳細地描述了實現 - 它的目的僅僅是開車回家,我確實確保在UI線程上創建和執行AsyncTask。我可以添加代碼來演示我正面臨的問題,但我會在省略此方面的情況下執行此操作。 – Travis 2012-03-14 02:07:00

回答

4

上調用ActivityUnitTestCase#startActivity UI線程解決了我的問題。

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