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();
}
}