2012-03-19 27 views
9

我已经看到一堆与此相关的帖子,但没有一篇似乎遇到同样的问题。 GetBusinessRulesTask扩展了AsyncTask。当我在单元测试用例中执行这个时,onPostExecute()永远不会被调用。但是,如果我使用真实的客户端代码,则每次都会调用onPostExecute()。不知道我在这里做错了什么。AsyncTask onPostExecute()未在单元测试用例中调用

测试用例:

package com.x.android.test.api; 

import java.util.concurrent.CountDownLatch; 

import android.test.ActivityInstrumentationTestCase2; 
import android.test.UiThreadTest; 
import android.widget.Button; 

import com.x.android.api.domain.businessrule.BusinessRules; 
import com.x.android.api.exception.NetworkConnectionException; 
import com.x.android.api.tasks.GetBusinessRulesTask; 
import com.x.android.test.activity.SimpleActivity; 

public class GetBusinessRulesTaskTest 
    extends 
     ActivityInstrumentationTestCase2<SimpleActivity> { 
SimpleActivity mActivity; 
Button mButton; 

public GetBusinessRulesTaskTest() { 
    super("com.x.android.test.activity", SimpleActivity.class); 
} 

@Override 
protected void setUp() throws Exception { 
    super.setUp(); 
    mActivity = this.getActivity(); 
    mButton = (Button) mActivity 
      .findViewById(com.x.android.test.activity.R.id.b1); 
} 

public void testPreconditions() { 
    assertNotNull(mButton); 
} 

@UiThreadTest 
public void testCallBack() throws Throwable { 
    final CountDownLatch signal = new CountDownLatch(1); 
    final GetBusinessRulesTask task = (GetBusinessRulesTask) new GetBusinessRulesTask(
      new GetBusinessRulesTask.Receiver<BusinessRules>() { 
       @Override 
       public void onReceiveResult(BusinessRules rules, Exception e) { 
        assertNotNull(rules); 
        assertNull(e); 
        signal.countDown();// notify the count down latch 
       } 
      }); 
    task.start(mActivity.getApplicationContext()); 
    try { 
     signal.await();// wait for callback 
    } catch (InterruptedException e1) { 
     fail(); 
     e1.printStackTrace(); 
    } 
} 
} 

OnPostExecute:

@Override 
protected void onPostExecute(AsyncTaskResponse<O> response) { 
    Log.d(TAG, "onPostExecuted"); 
    if (mReceiver != null) { 
     mReceiver.onReceiveResult(response.getResponse(), response.getException()); 
    } 
} 

DoInBackground:

@Override 
protected AsyncTaskResponse<O> doInBackground(I... params) { 
    Log.d(TAG, "doInBackgroundr"); 
    try { 
     Uri uri = createUri(params); 
     mBaseRequest = new GetLegacyRequest(uri); 
     String json = mBaseRequest.executeRequest(); 
     O response = deserializeJson(json); 
     Log.d(TAG, "Returning AsyncTaskResponse"); 
     return new AsyncTaskResponse<O>(response, null); 
    } catch (Exception e) { 
     Log.e(TAG, "Error", e); 
     /* 
     AsyncTaskResponse<O> maintenance = ReadBusinessControlledPropertiesTask.blockingCall(mServiceLocatorUrl); 
     if(maintenance.getException() == null) { 
      MaintenanceException mExcep = new MaintenanceException(maintenance.getResponse()); 
      if (mExcep.isUnderMaintenance()) 
       return new AsyncTaskResponse(null,mExcep); 
     }*/ 
     return new AsyncTaskResponse<O>(null, e); 
    } 
} 

Start方法()

public AsyncTask<Void, Void, AsyncTaskResponse<BusinessRules>> start(
     Context context) throws NetworkConnectionException { 
    super.start(context); 
    Log.d(TAG, "start"); 
    return execute(); 
} 

发现问题。不要让你的AsyncTask最终放到可运行的目录中。

的修复:

public void testCallBack() throws Throwable { 
    final CountDownLatch signal = new CountDownLatch(1); 
    // Execute the async task on the UI thread! THIS IS KEY! 
    runTestOnUiThread(new Runnable() { 
    @Override 
     public void run() { 
      try { 
       GetBusinessRulesTask task = (GetBusinessRulesTask)new GetBusinessRulesTask(new GetBusinessRulesTask.Receiver<BusinessRules>() { 
          @Override 
          public void onReceiveResult(
            BusinessRules rules, Exception e) { 
           assertNotNull(rules); 
           assertNull(e); 
           signal.countDown();// notify the count downlatch 
          } 
         }); 
       task.start(mActivity.getApplicationContext()); 
      } catch (Exception e) { 
       Log.e(TAG, "ERROR", e); 
       fail(); 
      } 
     } 
    }); 
    try { 
     signal.await();// wait for callback 
    } catch (InterruptedException e1) { 
     fail(); 
     e1.printStackTrace(); 
    } 
} 
+0

这是怎么回事这个'start'方法('task.start(mActivity.getApplicationContext());')?它只是设置了一些东西,并调用“执行”? – kabuko 2012-03-19 18:11:33

+0

我在上面添加了更多的代码。 – LowDev1 2012-03-19 18:33:08

+0

如果您将答案作为实际答案发布,而不仅仅是问题内容,​​那最好。 – PearsonArtPhoto 2012-03-20 14:47:12

回答

5

FOUND问题。不要让你的AsyncTask最终放到可运行的目录中。

的修复:

public void testCallBack() throws Throwable { 
    final CountDownLatch signal = new CountDownLatch(1); 
    // Execute the async task on the UI thread! THIS IS KEY! 
    runTestOnUiThread(new Runnable() { 
     @Override 
     public void run() { 
      try { 
       GetBusinessRulesTask task = (GetBusinessRulesTask)new GetBusinessRulesTask(new GetBusinessRulesTask.Receiver<BusinessRules>() { 
          @Override 
          public void onReceiveResult(
            BusinessRules rules, Exception e) { 
           assertNotNull(rules); 
           assertNull(e); 
           signal.countDown();// notify the count downlatch 
          } 
         }); 
       task.start(mActivity.getApplicationContext()); 
      } catch (Exception e) { 
       Log.e(TAG, "ERROR", e); 
       fail(); 
      } 
     } 
    }); 
    try { 
     signal.await();// wait for callback 
    } catch (InterruptedException e1) { 
     fail(); 
     e1.printStackTrace(); 
    } 
} 
+0

我有完全相同的问题,并修复它。谁能解释为什么? – tronbabylove 2013-02-26 21:55:30

+1

TestCase在与应用程序的实际UI线程分离的线程中运行。因此,为了在正确的线程上获得回调,它需要在您创建的线程中发生。所以在上面的代码中,你可以在你创建的runnable的同一个线程上获得回调。 – LowDev1 2013-04-18 13:45:39

相关问题