4

我正在为我的Android项目编写一个非常简单的单元测试用例,测试用例简单地执行AsyncTask,它在后台执行网络操作。我伸出AndroidTestCase类为我的测试案例:AsyncTask的onPostExecute()永远不会在AndroidTestCase中调用

public class MyTest extends AndroidTestCase{ 
    //use CountDownLatch to perform wait-notify behavior 
    private CountDownLatch signal; 
    @Override 
    public void setUp() throws Exception{ 
    super.setUp(); 
    //I use CountDownLatch to perform wait-notify behaviour 
    signal = new CountDownLatch(1); 
    } 

    @Override 
    public void runTest() throws Exception{ 
     String params = "some params"; 
     //MyAsyncTask does the networking tasks 
     new MyAsyncTask().execute(params); 

     //wait until MyAsyncTask is done 
     try { 
     signal.await(); 
     } catch (InterruptedException e) { 
     e.printStackTrace(); 
     } 

    } 

    private class MyAsyncTask extends AsyncTask<String, Void, String>{ 

    @Override 
    protected String doInBackground(String... params) { 
      //Do networking task e.g. access a remote database 
    } 

    @Override 
    protected void onPostExecute(String result){ 
     super.onPostExecute(result); 
      //this never get called when run this test case, why? 
      Log.i("Debug","post execute");  
      signal.countDown(); 
    } 
    } 
} 

正如你看到的上面,我使用CountDownLatch执行等待通知行为。

MyAsicTask后开始,我调用signal.await()等待MyAsyncTask完成。

onPostExecute()回调MyAsyncTask,我打电话给signal.countDown()通知任务已完成。

但是当我运行这个测试用例时,onPostExecute是从来不叫的,为什么&如何解决呢?

========更新==========我在runTest()添加Thread.sleep(30*1000)作为最后一行

后,我可以看到从网络操作更加日志。它证明teardown()在我的网络操作完成之前被调用。我在tearDown(),android测试框架中没有做任何事情。自动调用它。

看起来我的等待通知通过使用CountDownLatch不工作...为什么?

+1

doInBackground中的任何异常? – Triode

+0

'doInBackground'可能有问题,因此'onPostExecute'没有得到调用。 – d3m0li5h3r

+0

@ d3m0li5h3r除非doInbackground()崩溃并取消异步任务,否则onPostExecute()将无法执行。 –

回答

0

我认为你的网络操作是非常耗时的过程,所以它需要很长时间才能调用onPostExecute()方法。

+0

因为Android不允许网络操作在主线程(UI线程)中,所以我必须把它放在后台线程中。 – Mellon

1

因为我有同样的问题......这是为我解决它。 而不是让类扩展AndroidTestCase让它扩展InstrumentationTestCase。

然后我开始的AsyncTask是这样的:

runTestOnUiThread(new Runnable() 
    { 
     @Override 
     public void run() 
     { 
      startAsyncTask(); 
     } 
    }); 
0

确保您的doInBackground方法是不是这个问题的原因。试试这个示例任务。并请分享日志结果。

private class MyAsyncTask extends AsyncTask<String, Void, String> { 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     Log.i("Debug", "onPreExecute"); 
    } 

    @Override 
    protected String doInBackground(String... params) { 
     Log.i("Debug", "doInBackground"); 
     return "operation finished"; 
    } 

    @Override 
    protected void onPostExecute(String result) { 
     super.onPostExecute(result); 
     Log.i("Debug", "onPostExecute"); 
     signal.countDown(); 
    } 

    @Override 
    protected void onCancelled() { 
     super.onCancelled(); 
     Log.i("Debug", "onCancelled"); 
    } 
} 

编辑:我不知道,有可能是一个问题AndroidTestCase S和AsyncTask s工作一段时间。我只是将你的代码复制到我的项目中,并使用AsyncTask进行测试(请参阅上面的任务)。在每次启动doInBackground之后,onPostExecute方法被调用成功。我用2分钟的睡眠模拟了一个长时间运行的任务,并且这也输入了onPostExecute方法。并在onPostExecute之后调用tearDown方法。

因此,您的问题可能是您的doInBackground方法中的一个循环。或者以某种方式取消它,并调用任务的onCancelled方法。

0

onPostExecute()应该在​​的调用者线程中运行。如果通过调用类似signal.await()的方式挂起该线程,则onPostExecute()将无法​​运行。所以在致电​​之后,你不能有signal.await()

相关问题