gpt4 book ai didi

使用 Android 测试框架进行 Android AsyncTask 测试

转载 作者:IT老高 更新时间:2023-10-28 13:05:49 25 4
gpt4 key购买 nike

我有一个非常简单的 AsyncTask 实现示例,但在使用 Android JUnit 框架对其进行测试时遇到问题。

当我在普通应用程序中实例化并执行它时,它工作得很好。但是,当它从任何 Android 测试框架类(即 AndroidTestCaseActivityUnitTestCaseActivityInstrumentationTestCase2 等)它的行为很奇怪:

  • 正确执行doInBackground()方法
  • 但它不会调用任何通知方法(onPostExecute()onProgressUpdate() 等)——只是默默地忽略它们而不显示任何错误。

这是一个非常简单的 AsyncTask 示例:

package kroz.andcookbook.threads.asynctask;

import android.os.AsyncTask;
import android.util.Log;
import android.widget.ProgressBar;
import android.widget.Toast;

public class AsyncTaskDemo extends AsyncTask<Integer, Integer, String> {

AsyncTaskDemoActivity _parentActivity;
int _counter;
int _maxCount;

public AsyncTaskDemo(AsyncTaskDemoActivity asyncTaskDemoActivity) {
_parentActivity = asyncTaskDemoActivity;
}

@Override
protected void onPreExecute() {
super.onPreExecute();
_parentActivity._progressBar.setVisibility(ProgressBar.VISIBLE);
_parentActivity._progressBar.invalidate();
}

@Override
protected String doInBackground(Integer... params) {
_maxCount = params[0];
for (_counter = 0; _counter <= _maxCount; _counter++) {
try {
Thread.sleep(1000);
publishProgress(_counter);
} catch (InterruptedException e) {
// Ignore
}
}
}

@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
int progress = values[0];
String progressStr = "Counting " + progress + " out of " + _maxCount;
_parentActivity._textView.setText(progressStr);
_parentActivity._textView.invalidate();
}

@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
_parentActivity._progressBar.setVisibility(ProgressBar.INVISIBLE);
_parentActivity._progressBar.invalidate();
}

@Override
protected void onCancelled() {
super.onCancelled();
_parentActivity._textView.setText("Request to cancel AsyncTask");
}

}

这是一个测试用例。这里的 AsyncTaskDemoActivity 是一个非常简单的 Activity,它提供了用于在模式下测试 AsyncTask 的 UI:

package kroz.andcookbook.test.threads.asynctask;
import java.util.concurrent.ExecutionException;
import kroz.andcookbook.R;
import kroz.andcookbook.threads.asynctask.AsyncTaskDemo;
import kroz.andcookbook.threads.asynctask.AsyncTaskDemoActivity;
import android.content.Intent;
import android.test.ActivityUnitTestCase;
import android.widget.Button;

public class AsyncTaskDemoTest2 extends ActivityUnitTestCase<AsyncTaskDemoActivity> {
AsyncTaskDemo _atask;
private Intent _startIntent;

public AsyncTaskDemoTest2() {
super(AsyncTaskDemoActivity.class);
}

protected void setUp() throws Exception {
super.setUp();
_startIntent = new Intent(Intent.ACTION_MAIN);
}

protected void tearDown() throws Exception {
super.tearDown();
}

public final void testExecute() {
startActivity(_startIntent, null, null);
Button btnStart = (Button) getActivity().findViewById(R.id.Button01);
btnStart.performClick();
assertNotNull(getActivity());
}

}

所有这些代码都运行良好,除了 AsyncTask 在 Android 测试框架中执行时不会调用它的通知方法这一事实。有什么想法吗?

最佳答案

我在实现一些单元测试时遇到了类似的问题。我必须测试一些与 Executors 一起使用的服务,并且我需要让我的服务回调与我的 ApplicationTestCase 类中的测试方法同步。通常测试方法本身在回调被访问之前完成,因此通过回调发送的数据不会被测试。尝试应用 @UiThreadTest bust 仍然无效。

我找到了以下方法,它有效,我仍然使用它。我只是使用 CountDownLatch 信号对象来实现等待通知(您可以使用 synchronized(lock){... lock.notify();},但这会导致代码丑陋)机制。

public void testSomething(){
final CountDownLatch signal = new CountDownLatch(1);
Service.doSomething(new Callback() {

@Override
public void onResponse(){
// test response data
// assertEquals(..
// assertTrue(..
// etc
signal.countDown();// notify the count down latch
}

});
signal.await();// wait for callback
}

关于使用 Android 测试框架进行 Android AsyncTask 测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2321829/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com