Android ServiceTestCase для IntentService - PullRequest
11 голосов
/ 12 июля 2011

Я сейчас пишу юнит-тесты для приложений 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?

Спасибо!

Ответы [ 5 ]

6 голосов
/ 24 октября 2013

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

2 голосов
/ 12 августа 2011

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

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

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

0 голосов
/ 20 февраля 2015

В Android Studio 1.1 при запуске тестов с использованием конфигурации Run / Debug | Средство тестирования Android на любом тестируемом модуле (UUT), который расширяет IntentService, код ServiceTestCase.java (JUnit?) Не вызывает метод onHandleIntent (намерение) в проверяемом оборудовании. 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 показано выше.

0 голосов
/ 19 ноября 2014

На данный момент это мой подход:

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

    
    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
    }
    
  2. В сервисе onStart мы проверяем наличие определенного переданного Extra и вызываем метод для тестирования.Это не будет выполнено, когда умышленное срабатывание 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();
        }
    }
    
0 голосов
/ 04 июля 2013

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

Thread.sleep(XXXXXXX); 

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

...