Android ServiceTestCase для IntentService

В настоящее время я пишу модульные тесты для приложения Android и наткнулся на следующую проблему:

Я использую ServiceTestCase для тестирования IntentService следующим образом:

@Override
public void setUp() throws Exception {
    super.setUp();      
}

public void testService()
{
    Intent intent = new Intent(getSystemContext(), MyIntentService.class);
    super.startService(intent);     
    assertNotNull(getService());        
}

Однако я заметил, что мой IntentService создан (означает, что вызывается onCreate), но я никогда не получаю вызов в onHandleIntent(Intent intent)

Кто-нибудь уже тестировал IntentService с классом ServiceTestCase?

Спасибо!

Ответ 1

Я только что начал тестировать свой собственный IntentService, и это оказалось немного головной болью.

По-прежнему пытаюсь разобраться, но для сценария, когда кажется, что вы не получили вызов своего метода onHandleIntent(), (я не очень хорошо разбираюсь в технических особенностях junit, поэтому прощайте мое использование терминологии ) это должно быть потому, что тестовая среда, основанная на вашем коде, на самом деле срывает или завершает метод тестирования после возвращения вызова к startService. Недостаточно времени для срабатывания onHandleIntent.

Я проверил приведенную выше теорию, добавив бесконечный цикл в свой тестовый пример - только тогда я могу увидеть, что мои логические операторы в onHandleIntent занесены в журнал.

Ответ 2

Это немного поздно, но я просто боролся с этим. Вы можете решить это, создав класс, который просто переопределяет onStart вашего сервиса, чтобы он напрямую вызывал onHandleIntent. Например, если у вас есть LocationUpdaterService, вы можете создать поддельный класс, который переопределяет функцию onStart следующим образом:

public class LocationUpdaterServiceFake extends LocationUpdaterService {

@Override
public void onStart(Intent intent, int startId) {
    onHandleIntent(intent);
    stopSelf(startId);
}

LocationUpdaterService является подклассом IntentService, поэтому, когда вы пишете свои тесты, просто используйте класс LocationUpdaterServiceFake, подобный этому

public class LocationUpdateServiceTest extends ServiceTestCase<LocationUpdaterServiceFake> {

public LocationUpdateServiceTest()
{
    super(LocationUpdaterServiceFake.class);
}

public void testNewAreaNullLocation()
{
    Intent intent = new Intent();
    intent.setAction(LocationUpdaterService.ACTION_NEW_AREA);

    startService(intent);
}

}

Теперь, когда вы вызываете startService, он обходит код потока в IntentService и просто вызывает вашу функцию onHandleIntent

Ответ 3

Вам просто нужно добавить:

Thread.sleep(XXXXXXX); 

Выберите XXXX после startService, затем он передаст поток в метод onHandleIntent.

Ответ 4

В Android Studio 1.1 при запуске тестов с использованием конфигурации Run/Debug | Android Tests на любом модуле под тестовым кодом (UUT), который расширяет IntentService, код ServiceTestCase.java(JUnit?) Не вызывает метод onHandleIntent (намерение намерения) в UUT. ServiceTestCase только вызывает onCreate, поэтому проблема находится в тестовом коде.

protected void startService(Intent intent) {
    if (!mServiceAttached) {
        setupService();
    }
    assertNotNull(mService);

    if (!mServiceCreated) {
        mService.onCreate();
        mServiceCreated = true;
    }
    mService.onStartCommand(intent, 0, mServiceId);

    mServiceStarted = true;
}

В моем файле smSimulatorTest.java:

public class smSimulatorTest extends ServiceTestCase<smSimulator> 

В этот момент я ищу другие решения в рамках тестирования, которые тестируют UUT через Intents, так как это как экземпляр IntentService.

http://developer.android.com/reference/android/app/IntentService.html - Чтобы использовать его, расширьте IntentService и реализуйте onHandleIntent (Intent). IntentService получит Intents, запустит рабочий поток и прекратит обслуживание по мере необходимости.

Я, как и другие, поместил свой код в onHandleintent() в соответствии с приведенной выше документацией, однако ServiceTestCase тестирует onStart и onStartCommand, показанные выше.

Ответ 5

Это мой подход:

  • Начальное намерение, вызывающее службу, указывает метод службы для проверки

    
    public void test_can_do_the_work() {
        Intent startIntent = new Intent();
        startIntent.putExtra("IN_TEST_MODE", "TEST_SPECIFIC_METHOD");
        startIntent.setClass(getContext(), MyServiceToTest.class);
        startService(startIntent);
        assertNotNull(getService()); // Your assertion Service specific assertion
    }
    
  • В службе onStart мы проверяем конкретный экстент и передаем метод для тестирования. Это не будет выполняться, если умывка Handle запущена.

    
    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        String in_test_mode = intent.getStringExtra("TEST_SPECIFIC_METHOD");
        if(in_test_mode != null){
            doServiceWork();
        }
    }