【问题标题】:AsyncTask onPostExecute() not called in Unit Test Case单元测试用例中未调用 AsyncTask onPostExecute()
【发布时间】:2012-03-19 17:21:08
【问题描述】:

我看过很多与此相关的帖子,但似乎没有一个与我遇到的问题相同。 GetBusinessRulesTask 扩展了 AsyncTask。当我在单元测试用例中执行此操作时,永远不会调用 onPostExecute()。但是,如果我使用真正的客户端代码,那么每次都会调用 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);
    }
}

启动方法()

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

【问题讨论】:

  • start 方法 (task.start(mActivity.getApplicationContext());) 中发生了什么?它只是设置一些东西并调用execute吗?
  • 我在上面添加了更多代码。
  • 最好将您的答案作为实际答案发布,而不仅仅是在问题内。

标签: android unit-testing


【解决方案1】:

找到了问题。不要将您的 AsyncTask 设为 final 并将其放入可运行文件中。

修复:

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

【讨论】:

  • 我遇到了完全相同的问题,这解决了它。谁能解释一下为什么?
  • TestCase 在与应用程序的实际 UI 线程不同的线程中运行。因此,为了在正确的线程上获得回调,它需要在您创建的线程中发生。因此,在上面的代码中,您将在与您创建的可运行对象相同的线程上获得回调。
猜你喜欢
  • 1970-01-01
  • 2013-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多