2016-07-19 12 views
0

Mit Android Studio, beim Testen eines Stück Code, der Threads verwendet, fand ich eine gute Lösung, um zu überprüfen, eine Ausnahme ausgelöst wird. Mit UncaughtExceptionHandler auf den Thread im Test und join() warten, bis dieser Thread beendet ist.Junit Ausnahmen in separaten Thread mit Coverage

Alles funktioniert perfekt auf einen normalen Testlauf und sogar auf Debug. Das Problem tritt auf, wenn es mit Coverage ausgeführt wird. UncaughtExceptionHandler wird nie mit der ausgelösten Ausnahme aufgerufen, und daher schlägt der Test fehl, da eine Ausnahme erwartet wird.

Eine der Hypothesen, die ich habe, ist, dass der Thread so läuft, dass er keine ungeprüften Ausnahmen (dh mit einem Haken woanders) auslöst. Aber ich weiß nicht, wie ich dies validieren oder lösen kann Ich kann nicht gleichzeitig debuggen und mit Coverage laufen.

Antwort

0

Um Assertionen von anderen Threads auszuführen, überprüfen Sie ConcurrentUnit. Es bietet eine Waiter durch die Sie Assertionen in einem beliebigen Thread ausführen können, während der Haupt-Thread Haupt warten ist. Jegliche Assertionsfehler verursachen die Prüfung nicht bestanden, wie erwartet:

Waiter waiter = new Waiter(); 

new Thread(() -> { 
    waiter.assertEquals(foo, bar); 
    waiter.resume(); 
}).start(); 

// Wait for resume or an assertion failure 
waiter.await(); 
0

Ich bin nicht sicher, ob Android-Test verwendet die gleiche Junit api ich gewohnt bin in Thick-Client-Java, aber ich würde verwenden, um die ErrorCollector TestRule, um die Off-Thread-Prozessausnahmen zurück zum Haupttestthread zu ziehen, und ExpectedException, um zu überprüfen, dass ich den Ausnahmetyp, die Nachricht und/oder die Ursache der Ausführung erhalte.

import org.junit.Rule; 
import org.junit.Test; 
import org.junit.rules.ErrorCollector; 
import org.junit.rules.ExpectedException; 

public class ThreadExceptionTest { 
    @Rule 
    public ErrorCollector collector = new ErrorCollector(); 
    @Rule 
    public ExpectedException exEx = ExpectedException.none(); 

    @Test 
    public void doThreadTestFail() throws Exception { 
     Runnable r = new Runnable() { 

      @Override 
      public void run() { 
       try { 
        throw new RuntimeException("drat"); 
       } catch (Exception ex) { 
        collector.addError(ex); 
       } 
      } 
     }; 
     Thread th = new Thread(r); 
     th.start(); 
     th.join(); 

    } 

    @Test 
    public void doThreadTestPass() throws Exception { 
     exEx.expect(RuntimeException.class); 
     exEx.expectMessage("drat"); 

     Runnable r = new Runnable() { 

      @Override 
      public void run() { 
       try { 
        throw new RuntimeException("drat"); 
       } catch (Exception ex) { 
        collector.addError(ex); 
       } 
      } 
     }; 
     Thread th = new Thread(r); 
     th.start(); 
     th.join(); 

    } 
}