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
учебный класс?
Спасибо!
5 ответов
Я только начал тестировать свой собственный IntentService
и это оказывается немного головной болью.
Все еще пытаюсь разобраться, но для сценария, где кажется, что вы не получаете вызов вашего метода onHandleIntent()
, (Я не очень хорошо разбираюсь в технических деталях junit
так что простите за использование терминологии) это должно быть потому, что тестовая структура, основанная на вашем коде, фактически разрушает или завершает тестовый метод после вашего вызова startService
возвращается. Недостаточно времени для onHandleIntent
быть вызванным.
Я проверил вышеупомянутую теорию, добавив бесконечный цикл в моем тестовом примере - только тогда я смогу увидеть свои операторы журнала в onHandleIntent
журнал.
Это немного поздно, но я просто боролся с этим. Вы можете решить эту проблему, создав класс, который просто переопределяет 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
функция
Вам просто нужно добавить:
Thread.sleep(XXXXXXX);
Выбрать XXXX
после startService, он позволит потоку перейти в onHandleIntent
метод.
В 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 было показано выше.
Это мой подход на данный момент:
Начальный Intent, который вызывает службу, указывает метод Service для тестирования
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 мы проверяем наличие определенного переданного 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(); } }