Mocking up WifiManager per test di unità Android

Sto cercando di implementare alcuni test di unità per un paio di classi che si affidano a WifiManager e ai ScanResults restituiti. Quello che vorrei fare è poter controllare i ScanResults che ricevo per testare una serie di condizioni diverse.

Purtroppo per me è stato molto difficile imbalsamare WifiManager (anche se suppongo di poter passare i riferimenti null del constructor nel mio MockWifiManager). Questo sarà solo il mio primo problema in quanto una volta che ho un MockWifiManager a giocare (se funziona perfino!) Dovrò creare con successo il mio ScanResults test che non ha un constructor pubblico (immagina che sia stato creato da qualche fabbrica da qualche parte).

  • Come visualizzare un PDF tramite il browser Web Android senza prima "scaricare"
  • Come call i methods di un servizio dall'attività?
  • Formato Widget DatePicker
  • Ciclo di vita di BroadcastReciever - variables statiche
  • Imansible submit risposta da AsyncTask a MainActivity
  • Come mostrare tutto il mondo e inserire marcatori su di esso?
  • Domande: Con esso non avendo un constructor pubblico posso anche estenderlo?

    Sto andando tutto questo sbagliato? Mi chiedo spesso come fare un task specifico, ma in realtà stanno cercando di risolvere un problema diverso nel modo sbagliato, forse è quello che sto facendo qui?

    Sono molto nuovo in android e quindi devo sfondare tutta questa funzionalità sta cercando di dire il minimo.

    Grazie per i tuoi input!

    Modifica: sto facendo un po 'di tempo per istanziare anche un MockWifiManager. Il constructor del gestore wifi prevede un tipo di IWifiManager che non sembra esistere nel SDK di Android.

  • (Android) Prendi il primo giorno della settimana
  • Come utilizzi Android Studio come ottengo un APK sottoscritto, non debug e allineato con zip?
  • com.android.dex.DexException: definiscono più file dex
  • Recuperare un elenco di paesi dall'operazione android
  • Non get il file apk aggiornato, il progetto in esecuzione sul android studio
  • Inserisci contatto in Android con ContattiContract
  • 3 Solutions collect form web for “Mocking up WifiManager per test di unità Android”

    Crea un'astrazione intorno a WifiManager. Usalo questo per la tua derisione. La roba implorante che non possiedi è dura e fragile. Se fatto bene dovresti essere in grado di commutare gli interni, e fininetworking con una API migliore.

    Per i tuoi test è ansible far girare / imbrogliare il gestore per i contenuti dei cuori. Per la produzione passerai in un caso concreto.

    Per quanto riguarda il tuo punto di cambiare il tuo codice solo per renderlo testabile che non è corretto. Innanzitutto dovresti imbrogliare i ruoli non i tipi come discusso nel documento di seguito. Google per ulteriori informazioni.

    In secondo luogo, la creazione di un'astrazione intorno al codice di terze parti è una buona pratica come affermato dal principio di inversione di dipendenza in SOLID. Dovresti sempre dipendere da astrazioni, piuttosto che da implementazioni concnetworking se sei test di unità o no.

    http://www.objectmentor.com/resources/articles/dip.pdf http://butunclebob.com/ArticlesS.UncleBob.PrinciplesOfOod

    Potresti provare a creare le istanze ScanResult usando la riflessione per accedere ai costruttori privati. Il codice potrebbe sembrare qualcosa di simile:

    try { Constructor<ScanResult> ctor = ScanResult.class.getDeclaredConstructor(null); ctor.setAccessible(true); ScanResult sr = ctor.newInstance(null); sr.BSSID = "foo"; sr.SSID = "bar"; // etc... } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } 

    Per altri modi di test, più volte convertire le informazioni da istanze come ScanResult e incapsulare solo le informazioni necessarie nei miei oggetti. Questi mi nutro al metodo che fa il duro lavoro. Questo rende i test più facili in quanto è ansible build facilmente questi oggetti intermedi senza contare sugli oggetti reali ScanResult.

    Mi sto lottando per un po 'per build ScanResult object ScanResult . Ho usato con successo questo approccio di riflessione sopra.

    Se qualcuno sta cercando un modo per clonare ScanResult object ScanResult (o qualsiasi altro object che implementa Parcelable interface Parcelable ) è ansible utilizzare questo approccio (la ho controllata correttamente in un test di unità):

     @RunWith(RobolectricTestRunner.class) @Config(manifest=Config.NONE) public class MovingAverageQueueTests { @Test public void parcelTest() { Parcel parcel = Parcel.obtain(); ScanResult sr = buildScanResult("01:02:03:04:05:06", 70); parcel.writeValue(sr); parcel.setDataPosition(0); // required after unmarshalling ScanResult clone = (ScanResult)parcel.readValue(ScanResult.class.getClassLoader()); parcel.recycle(); assertThat(clone.BSSID, is(equalTo(sr.BSSID))); assertThat(clone.level, is(equalTo(sr.level))); assertThat(clone, is(not(sameInstance(sr)))); } private ScanResult buildScanResult(String mac, int level) { Constructor<ScanResult> ctor = null; ScanResult sr = null; try { ctor = ScanResult.class.getDeclaredConstructor(null); ctor.setAccessible(true); sr = ctor.newInstance(null); sr.BSSID = mac; sr.level = level; } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return sr; } } 

    E per quanto riguarda le performance, questo controllo ingenuo:

     @Test public void buildVsClonePerformanceTest() { ScanResult sr = null; long start = System.nanoTime(); for (int i = 0; i < 1000000; i++) { sr = buildScanResult("01:02:03:04:05:06", 70); } long elapsedNanos = System.nanoTime() - start; LOGGER.info("buildScanResult: " + elapsedNanos); start = System.nanoTime(); for (int i = 0; i < 1000000; i++) { sr = cloneScanResult(sr); } elapsedNanos = System.nanoTime() - start; LOGGER.info("cloneScanResult: " + elapsedNanos); } 

    Ha mostrato questi risultati:

    Oct 26, 2016 3:25:19 PM com.example.neutrino.maze.MovingAverageQueueTests buildVsClonePerformanceTest INFO: buildScanResult: 202072179 26 ott 2016 3:25:21 PM com.example.neutrino.maze.MovingAverageQueueTests buildVsClonePerformanceTest INFO: cloneScanResult: 2004391903

    Quindi la clonazione in questo modo è 10 volte less efficace della creazione di istanze anche con la riflessione. So che questo test non è robusto come ottimizzazioni vengono fatte durante la compilazione … Tuttavia fattore di dieci è difficile da mitigare. Ho anche provato 10K iterazioni e poi il fattore era anche 100! Solo per tua informazione.

    PS get Parcel.obtain () e parcel.recycle fuori loop non aiuta

    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.