ServiceTestCase を使用してサービスの単体テストを作成しています。
サービスは基本的に、何らかの作業を行う AsyncTask を実行してから、onPostExecute() で別の処理を行います。
(仮想) デバイスでサービスを実行してデバッグすると、サービスは期待どおりに機能します。
しかし、ServiceTestCase を拡張するテストでは、doInBackground() にしか入りません。メソッドが戻ると、onPostExecute() は呼び出されません。AsyncTask が作業を完了する時間があるように、テストを sleep() にします。
これは簡略化されたサービスです。
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 が提供する環境は多少限定されているのでうまくいかないのではと思うのですが、何かできることはありますか?
乾杯、トルステン