4

我正在为我的 Android 项目编写一个非常简单的单元测试用例,测试用例简单地执行一个AsyncTask在后台进行网络操作的测试用例。我正在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它永远不会被调用,为什么以及如何修复它?

========更新==========

在我添加Thread.sleep(30*1000)为最后一行之后runTest(),我可以看到更多来自网络操作的日志。它证明teardown()在我的网络操作完成之前调用了。我在 Android 测试框架 tearDown() 中什么也没做。自动调用它。

似乎我的使用等待通知CountDownLatch不起作用......为什么?

4

4 回答 4

1

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

然后我像这样启动 asyncTask:

runTestOnUiThread(new Runnable()
    {
        @Override
        public void run()
        {
            startAsyncTask();
        }
    });
于 2013-10-29T08:25:16.947 回答
0

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

于 2013-10-28T13:27:40.463 回答
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 和s时可能会出现问题AsyncTask。我刚刚将您的代码复制到我的项目中并使用AsyncTask(请参阅上面的任务)对其进行了测试。之后每次启动doInBackground时,onPostExecute都会成功调用方法。我模拟了一个长时间运行的任务,睡眠 2 分钟,这也进入了onPostExecute方法。和tearDown之后调用的方法onPostExecute

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

于 2013-10-31T14:33:11.430 回答
0

onPostExecute()应该在 的调用者线程中运行execute()。如果该线程通过调用类似的东西被挂起signal.await()onPostExecute()则将无法运行。所以你不能signal.await()在调用后拥有execute()

于 2016-01-14T12:33:31.717 回答