Android: Unidad de prueba de un servicio

Actualmente estoy intentando escribir una aplicación de Android usando TDD. Me han dado la tarea de escribir un servicio que será muy importante en la aplicación.

Como por esta razón estoy tratando de escribir una prueba adecuada para el servicio. Las directrices de Android indican lo siguiente:

El tema Qué probar enumera las consideraciones generales para probar componentes de Android. Aquí hay algunas pautas específicas para probar un servicio:

  • Asegúrese de que onCreate () se llama en respuesta a Context.startService () o Context.bindService (). Del mismo modo, debe asegurarse de que onDestroy () se llama en respuesta a Context.stopService (), Context.unbindService (), stopSelf () o stopSelfResult (). Pruebe que su Servicio gestiona correctamente varias llamadas desde Context.startService (). Sólo la primera llamada activa Service.onCreate (), pero todas las llamadas activan una llamada a Service.onStartCommand ().

  • Además, recuerde que las llamadas de startService () no anidan, por lo que una sola llamada a Context.stopService () o Service.stopSelf () (pero no stopSelf (int)) detendrá el servicio. Debe probar que su Servicio se detiene en el punto correcto.

  • Pruebe cualquier lógica de negocio que implemente su Servicio. La lógica de negocio incluye la comprobación de valores no válidos, cálculos financieros y aritméticos, etc.

Fuente: Pruebas de servicio | Desarrolladores de Android

Todavía tengo que ver una prueba adecuada para estos métodos de ciclo de vida, múltiples llamadas a Context.startService (), etc Estoy tratando de averiguar esto, pero estoy actualmente en una pérdida.

Estoy intentando probar el servicio con la clase de ServiceTestCase:

import java.util.List; import CoreManagerService; import org.junit.After; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Before; import org.junit.Test; import android.app.ActivityManager; import android.app.ActivityManager.RunningServiceInfo; import android.content.Context; import android.content.Intent; import android.test.ServiceTestCase; import android.test.suitebuilder.annotation.SmallTest; import android.util.Log; /** * * This test should be executed on an actual device as recommended in the testing fundamentals. * http://developer.android.com/tools/testing/testing_android.html#WhatToTest * * The following page describes tests that should be written for a service. * http://developer.android.com/tools/testing/service_testing.html * TODO: Write tests that check the proper execution of the service's life cycle. * */ public class CoreManagerTest extends ServiceTestCase<CoreManagerService> { /** Tag for logging */ private final static String TAG = CoreManagerTest.class.getName(); public CoreManagerTest () { super(CoreManagerService.class); } public CoreManagerTest(Class<CoreManagerService> serviceClass) { super(serviceClass); // If not provided, then the ServiceTestCase will create it's own mock // Context. // setContext(); // The same goes for Application. // setApplication(); Log.d(TAG, "Start of the Service test."); } @SmallTest public void testPreConditions() { } @BeforeClass public static void setUpBeforeClass() throws Exception { } @AfterClass public static void tearDownAfterClass() throws Exception { } @Before public void setUp() throws Exception { super.setUp(); } @After public void tearDown() throws Exception { super.tearDown(); } @Test public void testStartingService() { getSystemContext().startService(new Intent(getSystemContext(), CoreManagerService.class)); isServiceRunning(); } private void isServiceRunning() { final ActivityManager activityManager = (ActivityManager)this.getSystemContext() .getSystemService(Context.ACTIVITY_SERVICE); final List<RunningServiceInfo> services = activityManager .getRunningServices(Integer.MAX_VALUE); boolean serviceFound = false; for (RunningServiceInfo runningServiceInfo : services) { if (runningServiceInfo.service.getClassName().equals( CoreManagerService.class.toString())) { serviceFound = true; } } assertTrue(serviceFound); } } 

¿Me estoy acercando a esto incorrectamente? ¿Debo usar una prueba de actividad para probar la vinculación del servicio contra?

Hay un ejemplo con JUnit 4 :

Servicio:

 /** * {@link Service} that generates random numbers. * <p> * A seed for the random number generator can be set via the {@link Intent} passed to * {@link #onBind(Intent)}. */ public class LocalService extends Service { // Used as a key for the Intent. public static final String SEED_KEY = "SEED_KEY"; // Binder given to clients private final IBinder mBinder = new LocalBinder(); // Random number generator private Random mGenerator = new Random(); private long mSeed; @Override public IBinder onBind(Intent intent) { // If the Intent comes with a seed for the number generator, apply it. if (intent.hasExtra(SEED_KEY)) { mSeed = intent.getLongExtra(SEED_KEY, 0); mGenerator.setSeed(mSeed); } return mBinder; } public class LocalBinder extends Binder { public LocalService getService() { // Return this instance of LocalService so clients can call public methods. return LocalService.this; } } /** * Returns a random integer in [0, 100). */ public int getRandomInt() { return mGenerator.nextInt(100); } } 

Prueba:

 public class LocalServiceTest { @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule(); @Test public void testWithBoundService() throws TimeoutException { // Create the service Intent. Intent serviceIntent = new Intent(InstrumentationRegistry.getTargetContext(), LocalService.class); // Data can be passed to the service via the Intent. serviceIntent.putExtra(LocalService.SEED_KEY, 42L); // Bind the service and grab a reference to the binder. IBinder binder = mServiceRule.bindService(serviceIntent); // Get the reference to the service, or you can call public methods on the binder directly. LocalService service = ((LocalService.LocalBinder) binder).getService(); // Verify that the service is working correctly. assertThat(service.getRandomInt(), is(any(Integer.class))); } } 
  • Reconocimiento de voz como servicio de fondo
  • Animar ImageView dentro de WindowManager en un servicio de Android
  • Cómo mostrar un cuadro de diálogo de un servicio
  • Crear notificación cada día
  • cómo abrir la configuración de accesibilidad de mi aplicación directamente?
  • ¿Puede existir un servicio de fondo sin su aplicación principal?
  • ¿Cómo eliminar todas las notificaciones cuando se cancela una aplicación de Android (actividad o servicio)?
  • ¿Cómo mantener un servicio con los oyentes vivo después de desatar en Android?
  • Cómo ensayar un servicio de Android que depende de una conexión de red
  • Servicio de Android: proceso vs. no
  • "No se puede realizar esta acción en una instancia no sellada" excepción java.lang.IllegalStateException
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.