2012-03-19 12 views
9

Ho visto un sacco di post relativi a questo, ma nessuno sembra avere lo stesso problema che sto ottenendo. GetBusinessRulesTask estende AsyncTask. Quando eseguo questo in un caso di test unitario, onPostExecute() non viene mai chiamato. Tuttavia, se utilizzo il codice client reale, onPostExecute() viene chiamato ogni volta. Non sono sicuro di cosa sto facendo male qui.AsyncTask onPostExecute() non chiamato in Unit Test Case

Caso

prova:

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

metodo Start()

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

TROVATO IL PROBLEMA. Non rendere il tuo AsyncTask finale e metterlo all'interno del runnable.

La correzione:

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

quello che sta succedendo in questo 'metodo start' (' task.start (mActivity.getApplicationContext()); ')? Installa semplicemente alcune cose e chiama 'execute'? – kabuko

+0

Ho aggiunto altro codice sopra. – LowDev1

+0

Sarebbe meglio se tu pubblicassi la tua risposta come una risposta reale, e non solo all'interno della domanda. – PearsonArtPhoto

risposta

5

TROVATO IL PROBLEMA. Non rendere il tuo AsyncTask finale e metterlo all'interno del runnable.

La correzione:

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

Ho avuto lo stesso identico problema e questo l'ha corretto. Qualcuno può spiegare perché? – tronbabylove

+1

TestCase viene eseguito in un thread separato dal thread dell'interfaccia utente effettivo dell'applicazione. Quindi, per ottenere il callback sul thread giusto, è necessario che si verifichi in un thread che si crea. Quindi nel codice sopra hai la callback sullo stesso thread del runnable che hai creato. – LowDev1