14

Robolectric を使用して、応答としてインテントをブロードキャストする IntentService をテストするにはどうすればよいでしょうか?

次のクラスを想定しています。

class MyService extends IntentService {
    @Override
    protected void onHandleIntent(Intent intent) {
        LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("action"));
    }
}

私のテストケースでは、次のようなことをしようとしています:

@RunWith(RobolectricTestRunner.class)
public class MyServiceTest{
    @Test
    public void testPurchaseHappyPath() throws Exception {

        Context context = new Activity();

        // register broadcast receiver
        BroadcastReceiver br = new BroadcastReceiver() {

            @Override
            public void onReceive(Context context, Intent intent) {
                // test logic to ensure that this is called
            }

        };
        context.registerReceiver(br, new IntentFilter("action"));

        // This doesn't work
        context.startService(new Intent(context, MyService.class));

    }

}

MyService は、このアプローチを使用して開始されることはありません。私は Robolectric に比較的慣れていないので、明らかな何かが欠けている可能性があります。startService を呼び出す前に、何らかのバインディングを行う必要がありますか? コンテキストで sendBroadcast を呼び出すだけでブロードキャストが機能することを確認しました。何か案は?

4

1 に答える 1

12

あなたがやろうとしているように、サービスの初期化をテストすることはできません。Robolectric で新しいアクティビティを作成すると、返されるアクティビティは実際にはShadowActivity(一種の) です。つまり、 を呼び出すとstartService、実際に実行されるメソッドは、を呼び出すだけのこのShadowApplication#startServiceメソッドです。これはそのメソッドの内容です:

@Implementation
@Override
public ComponentName startService(Intent intent) {
    startedServices.add(intent);
    return new ComponentName("some.service.package", "SomeServiceName-FIXME");
}

実際にはサービスをまったく開始しようとしないことに気付くでしょう。サービスを開始しようとしたことを示すだけです。これは、テスト対象のコードがサービスを開始する必要がある場合に役立ちます。

実際のサービスをテストする場合は、初期化ビットのサービス ライフサイクルをシミュレートする必要があると思います。このようなものがうまくいくかもしれません:

@RunWith(RobolectricTestRunner.class)
public class MyServiceTest{
    @Test
    public void testPurchaseHappyPath() throws Exception {

        Intent startIntent = new Intent(Robolectric.application, MyService.class);
        MyService service = new MyService();
        service.onCreate();
        service.onStartCommand(startIntent, 0, 42);

        // TODO: test test test

        service.onDestroy();
    }
}

私は Robolectric がBroadcastReceivers をどのように扱うかよく知らないので、省略しました。

編集@Before:JUnit /@Afterメソッドでサービスの作成/破棄を行うと、テストにonStartCommand「テストテストテスト」ビットのみを含めることができるようになるため、さらに理にかなっている場合があります。

于 2012-10-17T12:42:30.790 に答える