2012-03-19 17 views
9

Widziałem wiele postów związanych z tym, ale żaden nie wydaje się mieć ten sam problem, który dostaję. GetBusinessRulesTask rozszerza AsyncTask. Kiedy wykonuję to w jednostkowym przypadku testowym, onPostExecute() nigdy nie jest wywoływany. Jeśli jednak używam prawdziwego kodu klienta, funkcja onPostExecute() jest wywoływana za każdym razem. Nie jestem pewien, co robię źle tutaj.Funkcja AsyncTask onPostExecute() nie jest wywoływana w jednostce testowej

Przypadek Testowy:

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); 
    } 
} 

metoda start()

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

ZNALAZŁE PROBLEM. Nie twórz AsyncTask końcowy i umieścić go w runnable.

Rozwiązaniem:

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

Co się dzieje w tej metodzie start' '(' task.start (mActivity.getApplicationContext()); ')? Czy to tylko niektóre rzeczy i wywołanie 'execute'? – kabuko

+0

Dodałem więcej kodu powyżej. – LowDev1

+0

Najlepiej byłoby, gdybyś opublikował swoją odpowiedź jako rzeczywistą odpowiedź, a nie tylko wewnątrz pytania. – PearsonArtPhoto

Odpowiedz

5

FOUND problem. Nie twórz AsyncTask końcowy i umieścić go w runnable.

Rozwiązaniem:

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

Miałem dokładnie ten sam problem i to naprawiło. Czy ktoś może wyjaśnić, dlaczego? – tronbabylove

+1

TestCase działa w oddzielnym wątku od rzeczywistego wątku interfejsu aplikacji. Aby uzyskać wywołanie zwrotne w odpowiednim wątku, musi się zdarzyć w wątku, który tworzysz. Tak więc w powyższym kodzie otrzymujesz wywołanie zwrotne w tym samym wątku, co uruchamianie, które tworzysz. – LowDev1

Powiązane problemy