2014-04-27 69 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上的分享,这对于许多努力让它工作的人来说是真正的帮助! –