2012-03-19 5 views
9

Я видел кучу сообщений, связанных с этим, но ни один из них не имеет той же проблемы, которую я получаю. GetBusinessRulesTask расширяет AsyncTask. Когда я выполняю это в единичном тестовом примере, onPostExecute() никогда не вызывается. Однако, если я использую настоящий клиентский код, то onPostExecute() вызывается каждый раз. Не уверен, что я делаю неправильно здесь.AsyncTask onPostExecute() не вызывается в модульном тестовом примере

Test Case:

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 и помещайте его в runnable.

Исправление:

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()); ')? Он просто устанавливает некоторые вещи и вызывает 'execute'? – kabuko

+0

Я добавил еще код выше. – LowDev1

+0

Было бы лучше, если бы вы отправили свой ответ в качестве фактического ответа, а не только внутри вопроса. – PearsonArtPhoto

ответ

5

НАЙДЕНО ПРОБЛЕМУ. Не делайте свой окончательный вариант AsyncTask и помещайте его в runnable.

Исправление:

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

+1

TestCase работает в отдельном потоке из фактического потока пользовательского интерфейса приложения. Поэтому, чтобы получить обратный вызов в правильном потоке, это должно произойти в потоке, который вы создаете. Таким образом, в коде выше вы получаете обратный вызов в том же потоке, что и созданный вами runnable. – LowDev1

Смежные вопросы