2014-04-27 68 views
0

我想使用Espresso來測試網絡電話。我製作了一個小測試應用程序,以查看是否可以在不使用AsyncTask的情況下使其工作。在獲取數據後,TextView會告訴用戶通話是否成功。我正在一個新的線程中進行網絡調用。Android Espresso與自定義資源同步

在我的測試中,我試着將AdvancedSynchronizationTest作爲一種模式讓測試等待,直到網絡請求被滿足。然而,我的實施似乎並不奏效。我的理解是,我重寫的方法在回調返回到主活動之前結束。如果是這樣的話,我會覆蓋錯誤的課程。我也嘗試覆蓋runnable本身(請參見下面的示例),甚至將UI更新更改爲設置布爾值,但結果並不相同。很顯然,Espresso不喜歡我使用另一個線程,但爲什麼它不應該等到線程完成?沒有使用AsyncTask會有什麼選擇?

您可以在這裏看到整個項目:https://github.com/bqmackay/EspressoCustomThreadingResourceExample

這裏是有問題的代碼:

MainActivityTest

public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> { 
... 
    @Override 
    protected void setUp() throws Exception { 
     super.setUp(); 
     getActivity(); 

     Runnable runnable = getActivity().getDownloadHelper().getWebCallRunnable(); 
     CountingIdlingResource countingIdlingResource = new CountingIdlingResource("WebCallRunnableCall"); 
     getActivity().getDownloadHelper().setWebCallRunnable(new DecoratedWebCallRunnable(runnable, countingIdlingResource)); 
     registerIdlingResources(countingIdlingResource); 
    } 

    public void testThreadRetrieval() throws Exception { 
     onView(withText("Thread")).perform(click()); 
     assertTrue(getActivity().isDidThreadReturn()); 
     //onView(withText("Thread Retrieved")).check(matches(isDisplayed())); 
    } 

    private class DecoratedWebCallRunnable implements Runnable { 

     private final Runnable realRunnable; 
     private final CountingIdlingResource countingIdlingResource; 

     private DecoratedWebCallRunnable(Runnable realRunnable, CountingIdlingResource countingIdlingResource) { 
      this.realRunnable = realRunnable; 
      this.countingIdlingResource = countingIdlingResource; 
     } 

     @Override 
     public void run() { 
      countingIdlingResource.increment(); 
      try { 
       realRunnable.run(); 
      } finally { 
       countingIdlingResource.decrement(); 
      } 
     } 
    } 

DownloadHelper

public class DownloadHelper { 
    private Runnable webCallRunnable; 

    private Runnable createWebCallRunnable() { 
     return new Runnable() { 
     @Override 
     public void run() { 
      HttpClient httpclient = new DefaultHttpClient(); 
      HttpResponse response = null; 
      try { 

       response = httpclient.execute(new HttpGet("http://whoismyrepresentative.com/getall_mems.php?zip=84020")); 
       StatusLine statusLine = response.getStatusLine(); 
       if(statusLine.getStatusCode() == HttpStatus.SC_OK){ 
        ByteArrayOutputStream out = new ByteArrayOutputStream(); 
        response.getEntity().writeTo(out); 
        out.close(); 
        repsCallbackInterface.onRepsThreadReceived(true); 
       } else{ 
        //Closes the connection. 
        response.getEntity().getContent().close(); 
        repsCallbackInterface.onRepsThreadReceived(false); 
        throw new IOException(statusLine.getReasonPhrase()); 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
     }; 
    } 
} 

MainActivity

public class MainActivity extends Activity implements RepsCallbackInterface { 
    .... 
    @Override 
    public void onRepsThreadReceived(final boolean didReceive) { 
     setDidThreadReturn(true); 
     runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       threadText.setText(didReceive ? "Thread Retrieved" : "Thread Failed"); 
      } 
     }); 
    } 
} 

回答

2

你並沒有真正提供這樣的問題在這裏,所以我屁股這個問題是關於爲什麼這個設置沒有按預期工作。

有(至少)有兩個原因:

  1. 斷言assertTrue(getActivity().isDidThreadReturn());testThreadRetrieval()不會等待所有要完成IdlingResources。只有ViewInteraction.check()ViewInteraction.perform()知道這些,並會在嘗試應用ViewAssertionViewAction之前檢查IdlingResources。

  2. 即使不是應用assertTrue()後註釋掉線,它是行不通的,因爲儀器線程是獨立的,不等待在getReps()創建啓動新的線程,所以IdlingResources的檢查可以並且會在CountingIdlingResource遞增之前發生。

如果出於某種原因,你真的不希望使用的AsyncTask,您仍然可以從咖啡通過其執行看着AsynTask線程池獲利。因此,不要單獨啓動一個線程,只需將Runnable提交到AsyncTask.THREAD_POOL_EXECUTOR即可。

+0

如果你有Android工作室(gradle proj。)中有工作空閒資源的任何項目,請與github上的分享,這對於許多努力讓它工作的人來說是真正的幫助! –