Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AsyncTask onPostExecute() not called in Unit Test Case

I've seen a bunch of posts related to this, but none seem to have the same issue I'm getting. GetBusinessRulesTask extends AsyncTask. When I execute this in a unit test case the onPostExecute() never gets called. However, if I use the real client code then onPostExecute() is called everytime. Not sure what I'm doing wrong here.

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 method()

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

FOUND THE ISSUE. Don't make your AsyncTask final and put it inside the runnable.

The fix:

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();
    }
}
like image 859
LowDev1 Avatar asked Mar 19 '12 17:03

LowDev1


Video Answer


1 Answers

FOUND THE ISSUE. Don't make your AsyncTask final and put it inside the runnable.

The fix:

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();
    }
}
like image 151
LowDev1 Avatar answered Oct 28 '22 01:10

LowDev1