2016-05-04 17 views
9

Ich versuche derzeit zu testen, dass eine Netzwerkantwort tatsächlich empfangen wird.Einheit testet eine Netzwerkantwort. Funktioniert beim Debuggen, nicht beim tatsächlichen Ausführen

Während ich verstehe, dass dies nicht ist, was ich in Bezug auf das Testen tun sollte, ist es eine Neugier aus eigenem Antrieb und ich würde gerne weitermachen, wenn möglich.

So wie es aussieht, habe ich erfolgreich den Test erstellt. Eine Anfrage wird ohne Probleme an eine Volley-Warteschlange gesendet.

Nun ist der ungeradee Teil:

Dieser Antrag nie ausgeführt wird. Hier ist eine Idee, wie ich es teste:

Dieser Code führt unerwartet dazu, den Test zu hängen und nie abgeschlossen.

aber das ist, wo ich zu verlieren, das Verständnis der Situation zu stoppen:

Wenn ich den Test über Debug und Schritt für Schritt durch zeilen laufen, führt der Test erfolgreich und Antwort empfangen wird.

Was ich denke, geschieht:

Wenn ich über Debug-Schritt durch, erfolgreich die Volley Request trägt auf und macht die Anforderung und die Antwort empfangen wird, bevor await() aufgerufen wird.

Wenn ich nicht über Debug durchlaufen, blockiert await() den Thread, der all das behandelt.

Irgendwelche Ideen, wie ich damit umgehen kann?

+0

@ Test? was ist das? – zgc7009

+0

Dies ist ein jUnit-Test, wie mein Tag vermuten lässt. – VicVu

+0

Wenn die Bestätigung fehlschlägt, wird countDown() niemals aufgerufen. Ich weiß nicht, wie sich Junit in einem Multithread-Test verhält, aber ich habe merkwürdiges Verhalten in dieser Situation mit anderen Test-Frameworks gesehen. –

Antwort

8

Volley stützt sich auf Looper.getMainLooper(), um seine Ausführungen zu handhaben. Wenn RobolectricTestRunner verwendet wird, macht Robolectric dies aus und wird daher nicht korrekt eingerichtet, was zu einem fehlgeschlagenen Test führt.

In meinem speziellen Fall, wenn ich Breakpoints verwendet, stellt das System den Hauptlooper ein, weil das System es verwendet, um die Breakpoints/Debugging-Tools anzuzeigen. Dies beschreibt also die Gründe für das Verhalten, das in meiner ursprünglichen Frage gefunden wurde.

Jetzt für eine Lösung, wie echte Netzwerkantworten mit Volley während eines Komponententests erhalten, muss der Executor geändert werden, um nicht den Hauptlooper zu verwenden.

Als einfache Lösung erstellen Sie eine Anforderungswarteschlange, die auf Executor.singleThreadExecutor() anstelle des Main Looper basiert.

Hier ist, was ich meine:

//Specific test queue that uses a singleThreadExecutor instead of the mainLooper for testing purposes. 
public RequestQueue newVolleyRequestQueueForTest(final Context context) { 
    File cacheDir = new File(context.getCacheDir(), "cache/volley"); 
    Network network = new BasicNetwork(new HurlStack()); 
    ResponseDelivery responseDelivery = new ExecutorDelivery(Executors.newSingleThreadExecutor()); 
    RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network, 4, responseDelivery); 
    queue.start(); 
    return queue; 
} 

Dann verwenden Sie diese als Ihre Anforderungswarteschlange für Volley während der Tests.

Der Schlüssel hier ist:

ResponseDelivery responseDelivery = new ExecutorDelivery (Executors.newSingleThreadExecutor());

Hoffe, das hilft!

+0

Können Sie Ihre Antwort ein wenig ausarbeiten, so dass sie auch für andere nützlich ist? – middlestump

+0

@middlestump ja sorry, ich hatte diese Antwort vergessen, nachdem ich auf eine der gleichen Art mit okhttp geantwortet habe. Aktualisierung mit Code jetzt. – VicVu

+0

danke jetzt ist es ein nützliches für ähnliche Fälle – middlestump