2015-07-20 22 views
6

sto cercando di testare il mio comportamento app con il caffè 2.2Come verificare IntentService iniziare

sull'attività principale, quando il pulsante premuto sia il servizio che un'altra attività viene avviato:

public class MainActivity extends Activity { 

    public void onButtonClicked() { 
     startActivity(SecondActivity.getStartIntent()); 
     startService(MyIntentService.getStartIntent()); 
    } 
} 

I' se i componenti vengono destinati iniziato m test:

public class MainActivityTest { 
    @Rule 
    public final IntentsTestRule<MainActivity> intentsRule = new IntentsTestRule<>(MainActivity.class, true); 

    @Test 
    public void shouldStartServiceOnButtonClicked() { 
     onView(withId(R.id.button)).perform(click()); 
     intended(hasComponent(hasClassName(SecondActivity.class.getName()))); 
     intended(hasComponent(hasClassName(MyIntentService.class.getName()))); 
    } 
} 

ma sto ottenendo errore:

Caused by: junit.framework.AssertionFailedError: Wanted to match 1 intents. Actually matched 0 intents. 

IntentMatcher: has component: has component with: class name: is "com.example.MyIntentService" package name: an instance of java.lang.String short class name: an instance of java.lang.String 

Matched intents:[] 

Recorded intents: 
-Intent { cmp=com.example/.SecondActivity (has extras) } handling packages:[[com.example]], extras:[Bundle[...]]) 
at junit.framework.Assert.fail(Assert.java:50) 

L'avvio di SecondActivity è registrato. Perché l'avvio del mio IntentService non è registrato (ho controllato che sia avviato)?

risposta

0

ho potuto fare un'ipotesi che il problema è che si sta legando a affermare che la IntentService è creato e funzionante subito dopo aver chiamato startService(), mentre in realtà il startService() non è chiamata sincronico. si verifica sul thread dell'interfaccia utente, ma non in modo corretto. puoi posticipare la convalida di alcuni stabilimenti e controllare se il servizio è iniziato.

+0

Come ho già scritto, ho verificato che il servizio venga avviato durante il runtime di test. Inoltre, nel mio test, verifica che l'intento sia registrato, non l'inizio del servizio. –

10

tl; dr non sembra come se questo è possibile date le attuali espresso-intenti fornito funzionalità

Ho scavato in giro per il codice sorgente dal momento che sto cercando di fare qualcosa di simile, e questo è quello che ho trovato:

l'agente di ricerca 'destinato' funziona guardando una lista di Intenti registrati. Questi vengono tracciati da un callback che viene registrato con l'istanza IntentMonitor quando viene chiamato Intents.init(). L'istanza IntentMonitor è definita dalla strumentazione corrente. Ogni volta che viene chiamato signalIntent() di IntentMonitor, verrà richiamato il callback in Intents.

Il problema sta nel fatto che signalIntent() non viene mai chiamato nel caso in cui si chiami activity.startService() con un intento. Questo perché signalIntent() nel caso AndroidJunitRunner viene richiamato solo dai metodi esposti su ExposedInstrumentationApi (che si verifica correlare solo ai vari metodi startActivity()). Per utilizzare espresso-intents con startService(), sembrerebbe che sia necessario un hook di strumentazione per startService() che consentirebbe di chiamare signalIntent() su IntentMonitor.

Non ho esperienza con l'aggiunta di strumentazione personalizzata ai miei apk di test, ma questa sarà la mia prossima strada di indagine. Aggiornerò la mia risposta se scoprirò tutto ciò che funziona.