2016-12-19 2 views
2

Ich versuche, Gerät meine ServiceHelper-Klasse zu testen, die eine Liste von Wifi-SSID zur Verfügung stellt, um aus meiner Sicht zu zeigen. So stelle ich eine beobachtbare Verwendung von RxJava + RxAndroid zur Verfügung. Wie Sie sehen können, habe ich die Observable.create() gewählt, um aus nativen Observablen (Arraylist of Items) zu erstellen, die auf eine BroadcastReceiver-Klasse angewiesen sind. Ich muss Einheit diese Methode testen. Ich habe keine gute Idee, wie man diese Art von Service testet oder verspottet, der von Sensoren abhängt.Unit-Test einen Dienst basierend auf BroadcastReceiver bekommen Liste von Wifi SSID und Rückgabe Rx.Observable

public class WifiPhoneServiceHelper { 

private Context context; 
private ArrayList<String> ssidList = new ArrayList<>(); 
private List<ScanResult> scanResultList; 
private WifiManager wifiManager; 

public WifiPhoneServiceHelper(Context context) { 
    this.context = context; 
} 

public Observable<ArrayList<String>> getObservableSsidWifiList() { 
    return Observable.create(new Observable.OnSubscribe<ArrayList<String>>() { 

     @Override 
     public void call(final Subscriber<? super ArrayList<String>> subscriber) { 
      wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); 

      final BroadcastReceiver receiver = new BroadcastReceiver() { 
       @Override 
       public void onReceive(Context context, Intent intent) { 
        if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { 
         scanResultList = wifiManager.getScanResults(); 
         for (int i = 0; i < scanResultList.size(); i++) { 
          String ssidDetected = scanResultList.get(i).SSID; 
          ssidList.add(ssidDetected); 
         } 
         subscriber.onNext(ssidList); 
        } 
       } 
      }; 

      context.registerReceiver(receiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)); 

      if (!wifiManager.isWifiEnabled()) { 
       wifiManager.setWifiEnabled(true); 
      } 
      wifiManager.startScan(); 

      subscriber.add(new MainThreadSubscription() { 
       @Override 
       protected void onUnsubscribe() { 
        context.unregisterReceiver(receiver); 
        Timber.d("unregisterReceiver BroadcastReceiver SCAN_RESULTS_AVAILABLE_ACTION"); 
        if (!subscriber.isUnsubscribed()) { 
         subscriber.unsubscribe(); 
        } 
       } 
      }); 
     } 
    }); 
} 

Antwort

1

Um Einheit testen Sie Ihren Code, den Sie Beschreibung aller Funktionen in separate Schnittstelle benötigen und es dann für Android implementieren und Mock-Implementierung für Unit-Tests (Mockito) erstellen.

+0

So kann ich wirklich die Liste der Wifi-SSIDs mit einem echten Android Phone-Gerät testen? Ich meine, was kann ich tun, um nicht die gesamte Anwendung in Runtime zu testen ... Ich möchte die bereitgestellte Liste von WIFI'ssid mit der Android-API aus dem SDK testen – AndroidLover

+0

Nein, Komponententests laufen auf Java-Maschine, um auf Android zu testen Verwenden Sie instrumentierte Tests. Auf diese Weise haben Sie echte Kontext von Android –

+0

Ok verstanden, also wie kann ich so einen instrumentierten Test verwenden, um diese Liste von Wifi-SSID aufzulisten? Ich kann ein Beispiel nicht finden, das funktioniert ... kann sein, weil ich nicht dieser Experte in der Prüfung bin ... Kannst du einen Link des Testcodes posten? Danke im Voraus ... – AndroidLover

1

Alex schlägt effektiv vor, dass Sie eine Schnittstelle zwischen Ihrem Code und dem Wi-Fi-System erstellen und im Produktionscode von Androids WifiManager implementiert haben, aber beim Testen von Ihrem eigenen Testkabelbaum implementiert werden.

Sie könnten das sicherlich tun, aber eine andere Option ist Robolectric. Dies ist ein Test-Framework für Android-Geräte, mit dem große Teile des Android-Systems abgespielt werden können, ohne dass dabei so viel Vorarbeit geleistet wird wie mit Mockito. Insbesondere kann es das Wi-Fi-System verspotten und Sie können daher vorgeben, dass ein bestimmtes Netzwerk existiert oder nicht. Die Vorteile dabei sind, dass Sie Ihren WLAN-Code weitgehend so lassen können, wie er ist, ohne dass Sie für den Test aufweichen müssen, aber Sie benötigen immer noch kein echtes Gerät und es ist nicht von der realen Netzwerkumgebung abhängig.

Insbesondere suchen Sie nach Beispielen rund um ShadowWifiManager. Die andere Hälfte des Puzzles produziert Ereignissendungen, um Ihren Code zu stimulieren, aber dies sollte auch machbar sein.

Es würde den Rahmen dieser Antwort sprengen, den Aufbau einer Robolectric-Testumgebung vollständig zu beschreiben, aber hoffentlich gibt Ihnen das etwas, womit Sie anfangen können, zu recherchieren.

+0

Vielen Dank, also muss ich diesen Job in zwei Schritte teilen: Schritt 1: Ich muss eine Schnittstelle namens beispielsweise Schnittstelle IWifiSsidProvider verwenden { ArrayList provideSsidWifiList (Kontextkontext); } dann verwende ich seine reale Welt Implementierung in meinem getObservableSsidWifiList() -Step zwei ist das Wifi-System mit ShadowWifiManager von Robotelectics verspotten. Aber was, wenn ich wirklich sicher sein möchte, dass dieser Code wirklich eine Liste der SSID zur Verfügung stellt und nicht in Runtime abstürzt? gibt es eine Möglichkeit, es mit einem echten Gerät zu testen, zum Beispiel mit einem instrumentierten Test? Und vielen Dank! – AndroidLover

+0

Statt zwei Schritte haben wir zwei verschiedene Möglichkeiten beschrieben. Wenn Sie Robolectric verwenden, müssen Sie keine Verbindung herstellen (Schritt 1).Aber wenn Sie auf einem realen Gerät in echten Netzwerken testen möchten, möchten Sie eigentlich eine * dritte * Option, die den echten Code unter der Instrumentierung ablaufen lässt - so ziemlich ein normaler Komponententest Ihres vorhandenen Codes, aber ein Gerät verwenden. Es gibt viel Material, das beschreibt, wie man instrumentierte Tests mit Android durchführt. –

+0

Vielen Dank Rob, jetzt kann ich es deutlich sehen, bitte schreiben Sie einige hilfreiche Links, damit ich diese Konversation beenden kann. :) – AndroidLover

Verwandte Themen