Подтвердить что ты не робот

Робоэлектрические и IntentServices

Используя 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 в контекст. Любые идеи?

4b9b3361

Ответ 1

Вы не можете протестировать инициализацию службы, как вы пытаетесь сделать. Когда вы создаете новое действие под 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 относится к BroadcastReceiver s, поэтому я его оставил.

РЕДАКТИРОВАТЬ. Может возникнуть еще больше смысла делать создание/уничтожение службы в методах JUnit @Before/@After, что позволит вашему тесту содержать только теги onStartCommand и "test test test".