AsyncTask.onPostExecute() 在 ServiceTestCase 中永远不会被调用
我正在使用 ServiceTestCase 为服务编写单元测试。
该服务基本上执行一个 AsyncTask,该任务执行一些工作,然后在 onPostExecute() 中执行其他操作。
当我在(虚拟)设备中运行和调试该服务时,该服务按预期工作。
但在扩展ServiceTestCase的测试中,我只进入了doInBackground()。一旦方法返回,onPostExecute() 就永远不会被调用。我让测试 sleep() 以便 AsyncTask 有时间完成其工作。
这是简化的服务:
public class ServiceToTest extends Service {
private AtomicBoolean busy = new AtomicBoolean(false);
@Override
public IBinder onBind(final Intent intent) {
return null;
}
@Override
public int onStartCommand(final Intent intent, final int flags,
final int startId) {
this.handleCommand();
return START_NOT_STICKY;
}
/**
* Workaround for http://code.google.com/p/android/issues/detail?id=12117
*/
@Override
public void onStart(final Intent intent, final int startId) {
this.handleCommand();
}
public void handleCommand() {
new TaskToTest().execute();
}
public boolean isBusy() {
return busy.get();
}
private class TaskToTest extends AsyncTask<Boolean, Void, TestInfo> {
@Override
protected void onPreExecute() {
busy.set(true);
}
@Override
protected TestInfo doInBackground(final Boolean... args) {
return null;
}
@Override
protected void onPostExecute(final TestInfo info) {
busy.set(false);
}
}
}
这是对它的测试:
public class ServiceTest extends ServiceTestCase<ServiceToTest> {
public ServiceTest() {
super(ServiceToTest.class);
}
public void testIsBusy() throws InterruptedException {
startService(new Intent("this.is.the.ServiceToTest"));
ServiceToTest serviceToTest = this.getService();
assertTrue(serviceToTest.isBusy());
Thread.sleep(10000);
assertFalse(serviceToTest.isBusy());
}
}
我认为 ServiceTestCase 提供的环境有些限制,所以这不起作用,但是有什么办法吗?无论如何,我能做些什么来让它发挥作用吗?
干杯, 托斯顿
I am writing a unit test for a service using ServiceTestCase.
The service basically executes an AsyncTask that does some work and then does something else in onPostExecute().
The service works as expected when I run and debug it in a (virtual) device.
But in the test extending ServiceTestCase, I only get into doInBackground(). Once the methods returns, onPostExecute() never gets called. I am letting the test sleep() so the AsyncTask has time to complete its work.
This is the simplified service:
public class ServiceToTest extends Service {
private AtomicBoolean busy = new AtomicBoolean(false);
@Override
public IBinder onBind(final Intent intent) {
return null;
}
@Override
public int onStartCommand(final Intent intent, final int flags,
final int startId) {
this.handleCommand();
return START_NOT_STICKY;
}
/**
* Workaround for http://code.google.com/p/android/issues/detail?id=12117
*/
@Override
public void onStart(final Intent intent, final int startId) {
this.handleCommand();
}
public void handleCommand() {
new TaskToTest().execute();
}
public boolean isBusy() {
return busy.get();
}
private class TaskToTest extends AsyncTask<Boolean, Void, TestInfo> {
@Override
protected void onPreExecute() {
busy.set(true);
}
@Override
protected TestInfo doInBackground(final Boolean... args) {
return null;
}
@Override
protected void onPostExecute(final TestInfo info) {
busy.set(false);
}
}
}
An this is the test for it:
public class ServiceTest extends ServiceTestCase<ServiceToTest> {
public ServiceTest() {
super(ServiceToTest.class);
}
public void testIsBusy() throws InterruptedException {
startService(new Intent("this.is.the.ServiceToTest"));
ServiceToTest serviceToTest = this.getService();
assertTrue(serviceToTest.isBusy());
Thread.sleep(10000);
assertFalse(serviceToTest.isBusy());
}
}
I suppose that the environment provided by ServiceTestCase is somewhat limited so this doesn't work, but is there anything I can do to make it work anyway?
Cheers,
Torsten
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
问题是您的后台线程正在等待 UI“活动”,您需要调用 Looper.prepare() 和 Looper.loop() 。 此页面对此进行了更好的解释。
The problem is that your background thread is waiting for the UI to be "alive", you need to call
Looper.prepare()
andLooper.loop()
. It's better explained in this page.所以只是为了跟进我如何让它与 dmon 提供的信息一起工作。
我将测试更改为以下内容:
公共类 ServiceTest 扩展 ServiceTestCase {
}
我现在将考虑使这个 ServiceTestThread 更加通用,以便可以重用。
托斯顿
So just to follow up on how I got it to work with the info provided by dmon.
I changed my test to the below:
public class ServiceTest extends ServiceTestCase {
}
I'll see now to make this ServiceTestThread more generic so it can be reused.
Torsten
不确定这对其他人是否有用,但这是我尝试抽象 Tortens 答案并使其更可重用。
Not sure if this is useful to anybody else, but this was my attempt at abstracting Tortens answer and making it more reusable.
当我尝试从测试运行程序线程而不是 ui 线程绑定到服务时,我遇到了同样的问题。尝试从 ui 线程调用 startService。
I had the same problem when attempting to bind to a service from the test runner thread, rather than the ui thread. Try calling startService from the ui thread.