2012-02-15 27 views
9

Tentativo di scrivere la mia prima app Android-by-TDD (ho scritto alcune piccole app Android senza TDD, quindi ho familiarità con l'ambiente), ma non riesco a capire come scrivere il mio primo test.Unit test chiamata Activity.startService()?

Lo scenario:

ho un'attività, TasksActivity, e di un servizio, TasksService. Devo testare che TasksActivity avvia TasksService nel suo metodo onStart().

Il test che ho scritto è questo:

public class ServiceControlTest extends ActivityUnitTestCase<TasksActivity>{ 
public ServiceControlTest() { 
    super(TasksActivity.class); 
} 

public void testStartServiceOnInit() { 
    final AtomicBoolean serviceStarted = new AtomicBoolean(false); 
    setActivityContext(new MockContext() { 
     @Override 
     public ComponentName startService(Intent service) { 
      Log.v("mockcontext", "Start service: " + service.toUri(0)); 
      if (service.getComponent().getClassName().equals (TasksService.class.getName())) 
       serviceStarted.set(true); 
      return service.getComponent(); 
     } 
    }); 
    startActivity(new Intent(), null, null); 
    assertTrue ("Service should have been started", serviceStarted.get()); 
}   
} 

Nel mio metodo onCreate() in TasksActivity ho:

startService(new Intent(this, TasksService.class)); 

Ho anche provato

getBaseContext().startService(new Intent(this, TasksService.class)); 

Ma in nessun caso viene chiamato il metodo startService del mio MockContext. C'è un modo per impostare l'intercettazione di questo metodo? Preferirei non dover iniziare a completare le API Android di base per eseguire test di base ...

+0

Si è verificato che il vostro 'di Activity'' onCreate() 'metodo viene sempre chiamato attraverso la strumentazione? Non vedo nulla di necessariamente sbagliato in quello che stai facendo lì. –

+0

Ora, è interessante. Non lo è. Né si chiama se faccio esplicitamente getInstrumentation(). CallActivityOnCreate (...). Ma è * chiamato * se commento il mio finto contesto ... ci deve essere una certa dipendenza dal contesto che fa qualcosa o altro per passare la chiamata. – Jules

+0

Sì. Trovato questo (http://www.paulbutcher.com/2011/03/mock-objects-on-android-with-borachio-part-2/), dai un'occhiata. In sostanza, 'MockContext' è quasi del tutto inutile :). –

risposta

6

Solo per riassumere la conversazione con Brian Dupuis nei commenti, il problema era che MockContext non fornisce servizi che sono richiesti dalla strumentazione di test per chiamare correttamente onCreate(). Passare da MockContext a ContextWrapper risolto questo problema.

La prova di lavoro appare quindi come questo:

public void testStartServiceOnInit() { 
    final AtomicBoolean serviceStarted = new AtomicBoolean(false); 
    setActivityContext(new ContextWrapper(getInstrumentation().getTargetContext()) { 
     @Override 
     public ComponentName startService(Intent service) { 
      Log.v("mockcontext", "Start service: " + service.toUri(0)); 
      if (service.getComponent().getClassName().equals ("net.meridiandigital.tasks.TasksService")) 
       serviceStarted.set(true); 
      return service.getComponent(); 
     } 
    }); 
    startActivity(new Intent(), null, null); 
    assertTrue ("Service should have been started", serviceStarted.get()); 
} 
+1

Con la deprecazione di ActivityTestCase e MockContext, si dispone di un'alternativa alla soluzione originale? Grazie! –