8

Non ho trovato alcun esempio su come farlo. Sto assumendo che non è possibile sulla base di esempi come questo:E 'possibile iniettare mock a scopo di test con AndroidAnnotations?

@Bean(MyImplementation.class) 
MyInterface myInterface; 

dove la classe di iniettare è già determinato.

+0

Stai cercando di testare la tua classe o la classe generata da AndroidAnnotations? –

+0

Voglio testare una classe che scrivo. Voglio iniettare mock nella classe che scrivo per il codice di test e iniettare oggetti "reali" per la produzione. – apollodude217

risposta

6

La domanda è: test di unità o test di integrazione?

Se si esegue il test delle unità, suggerirei di usare le mock alla vecchia maniera, utilizzando un setter e cercando di testare il codice Java senza il framework di dipendenze dell'iniezione. Questo metterà alla prova la tua classe in modo isolato e sottrae molta complessità.

quello che voglio dire:

public class Test{ 

    ClassInTest inTest; 
    MyInterface myInterface; 

    @Before 
    public void setup(){ 
     inTest = new ClassInTest(); 
     //or your favorite mocking frameowrk 
     myInterface = EasyMock.createMock(MyInterface.class); 
     inTest.setMyInterface(myInterface); 
    } 

    @Test 
    public void testMethod(){ 
     //...mocking test code 
    } 
} 

Naturalmente, testando Android Attività (e altre estensioni di Android) è difficile a causa dell'eccezione gettare mozziconi e classi/metodi finali. È qui che Robolectric è utile (e altamente consigliato) per creare un'istanza/ombreggiamento dell'API Android.

Se si sta eseguendo un test di integrazione, si consiglia di adottare un altro approccio. Personalmente, proverei a non deridere durante i test di integrazione mentre provo a testare l'applicazione come se fosse in produzione. Ma, se vuoi davvero prendere in giro, potresti usare un approccio simile al test delle unità e introdurre una simulazione dopo aver alzato la tua classe di attività generata. Vale la pena notare, è possibile eseguire test di integrazione direttamente sull'hardware utilizzando framework come Robotium.

Altro per la tua domanda, non sono a conoscenza di alcuna infrastruttura di AndroidAnnotation specificatamente per l'iniezione di Mock o l'introduzione di Mock nell'albero delle dipendenze iniettato di un'applicazione.

+0

Grazie. Ho iniziato a usare Robolectric per i test unitari. Nell'esempio che hai fornito sopra, stai dicendo di chiamare il costruttore della mia classe nel metodo di test per bypassare AndroidAnnotations durante i test del tutto? – apollodude217

+1

Chiamare il costruttore (con Robolectic coinvolto) ti fornisce solo un'istanza dell'attività. Non direi che ignora AndroidAnnotaions. Ma, se collaudi la tua classe "MyActivity" (vs "MyActivity_"), non avrai il codice generato responsabile di DI da AA. –

8

Un complemento alla johncarl risposta:

  • Non c'è alcun modo per dire AndroidAnnotations che si desidera iniettare prende in giro, invece di oggetti reali, perché funziona al momento della compilazione, in modo che il codice deve essere sempre di produzione pronto.

  • Si consiglia di testare le attività generate, in complemento con Robolectric. Le annotazioni stanno aggiungendo comportamenti al tuo codice, quindi non dovresti testarlo come se non ci fossero annotazioni.

  • Prestare attenzione a verificare il comportamento delle attività, non il comportamento di AndroidAnnotations. Il framework ha già dei test per verificare che le annotazioni funzionino correttamente :).

  • È possibile lasciare che AndroidAnnotations DI avvenga e quindi reinserire la dipendenza fittizia. I campi hanno almeno un ambito di default, il che significa che è possibile accedervi dallo stesso pacchetto, quindi dovresti creare il test nello stesso pacchetto dell'attività.

    MyActivity_ activity = new MyActivity_(); 
    
    // myInterface gets injected 
    activity.onCreate(null); 
    
    // you reinject myInterface 
    activity.myInterface = Mockito.mock(MyInterface.class); 
    
  • In AndroidAnnotations, dipendenze vengono iniettati chiamando MyImplementation_.getInstance_(). È possibile utilizzare la manipolazione bytecode di runtime con uno strumento come PowerMock per consentire al metodo getInstance_() di MyImplementation_ di restituire una simulazione. Questo potrebbe richiedere un po 'di lavoro iniziale, perché dovresti mixare il runner di test di PowerMock e il runner di prova di Robolectric.

Modifica: ho aggiornato il documentation con il contenuto basato su questa domanda.

+1

+1. È interessante che tu suggerisca di testare le Attività generate (pt.2). Immagino che ci siano abbastanza modifiche all'attività per giustificare questo approccio. –

+0

Questo è esattamente il mio punto :) –

+1

@ Piwaï Non sono sicuro di come funzionerà l'approccio derisorio di cui sopra. Se hai dei metodi annotati con AfterViews, questi verranno eseguiti come parte della creazione dell'attività. Se questi metodi hanno dipendenze, falliranno, poiché non hai ancora avuto la possibilità di prenderli in giro. Qualche idea su come aggirare questo? – Neil