3

Ich habe die folgende Hilfsmethode erstellt mit Test Observablen zu unterstützen:Wie Timeout-Verhalten mit TestScheduler zu erreichen?

public static void ExecuteObservableTest<T>(IObservable<T> observable, Action action, Action assert, bool expectTimeout, int timeout = 500) 
    { 
     Exception ex = null; 
     var scheduler = new TestScheduler(); 
     observable.Timeout(TimeSpan.FromMilliseconds(timeout)).ObserveOn(scheduler).Subscribe(_ => { }, e => ex = e); 
     action(); 
     scheduler.AdvanceBy(TimeSpan.FromMilliseconds(timeout).Ticks + 1); 
     assert(); 
     if (expectTimeout) Assert.IsNotNull(ex); 
     else Assert.IsNull(ex); 
    } 

Dinge groß arbeiten, solange ich kein Timeout erwarten. Für Testfälle, bei denen ich ein Timeout erwarte, erreicht diese Methode niemals die OnException-Methode. Was ist der richtige Weg, um dies mit TestScheduler zu erreichen?

Ich sollte auch beachten, dass das Timeout ein Soft-Timeout ist, was bedeutet, dass, wenn das Observable nicht innerhalb der zugewiesenen Zeit abgeschlossen wurde, es nie abgeschlossen wird - aber es gibt kein entsprechendes Timeout innerhalb der Observable selbst definiert.

Antwort

2

Sie müssen die TestScheduler zu Timeout mit this overload

var scheduler = new TestScheduler(); 
observable.Timeout(TimeSpan.FromMilliseconds(timeout), scheduler) 
      .Subscribe(_ => { }, e => ex = e); 
+0

Danke, @supertopi bereitzustellen. Wenn ich versuche, sowohl die Timeout-Überladung als auch ObserveOn (Scheduler) in derselben Anweisung zu verwenden, scheint letztere ignoriert zu werden, so dass meine Tests nun ein Timeout erwarten, während die anderen (früher bestanden) jetzt fehlschlagen. Ich habe einen if-else Block hinzugefügt um expectTimeout zu aktivieren. Weißt du, warum das passiert, und gibt es eine elegantere Lösung als eine if-Anweisung? – ket

+1

Sicher. Erstellen Sie einen 'ITestableObserver' mit' scheduler.CreateObserver '. Abonnieren Sie den testbaren Beobachter auf Ihre beobachtbare Testperson. Nachdem Sie TestScheduler für eine gewünschte Zeitspanne vorwärts bewegt haben, können Sie überprüfen, ob das Zeitlimit aufgetreten ist, etwa durch "testObserver.Messages.AssertEqual (OnError (timeout))" – supertopi

+1

@ket: Die Verwendung von 'ObserveOn' mit' TestScheduler' macht das nicht wirklich Sinn. "ObserveOn" hat einen anderen Zweck, z. Sie können sicherstellen, dass Sie die Benutzeroberfläche Ihrer Anwendung von einem Abonnement aus ändern können, wenn Sie den mit der Benutzeroberfläche verknüpften Scheduler (wie "DispatcherScheduler") "beobachten". 'TestScheduler' wird verwendet, um die Zeit zu" komprimieren "und sollte als Argument an Operationen übergeben werden, die darauf warten, dass die Zeit wie" Timeout "vergeht. –

Verwandte Themen