3

我已經創建了下面的輔助方法來協助測試觀測:如何使用TestScheduler完成超時行爲?

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); 
    } 

事情工作的偉大,只要我不期待超時。對於我確實期望超時的測試用例,此方法永遠不會達到OnException方法。使用TestScheduler實現這一點的正確方法是什麼?

我還應該注意到超時是一個軟超時,意思是說如果observable沒有在指定的時間內完成,它永遠不會完成 - 但是在observable本身沒有定義相應的超時。

回答

2

您需要提供TestSchedulerTimeoutthis overload

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

謝謝,@supertopi。當我試圖在同一個語句中同時使用Timeout重載和ObserveOn(調度程序)時,後者似乎被忽略,所以我的測試期望超時現在通過,而其他測試(以前通過)現在失敗。我添加了一個if-else塊來切換expectTimeout。你知道爲什麼會發生這種情況,是否有比if語句更優雅的解決方案? – ket

+1

當然。用'scheduler.CreateObserver '創建一個'ITestableObserver'。將可測試的觀察者訂閱到正在測試的可觀測值。在推進TestScheduler達所需的時間之後,你可以通過諸如'testObserver.Messages.AssertEqual(OnError(timeout))之類的東西來檢查超時是否發生了。' – supertopi

+1

@ket:在'TestScheduler'中使用'ObserveOn'並不真正使感。 'ObserveOn'具有不同的目的,例如如果您ObserveOn與UI關聯的調度程序(如「DispatcherScheduler」),則可以確保您可以從訂閱修改應用程序的UI。 'TestScheduler'用於「壓縮」時間,應該作爲一個參數傳遞給等待時間通過的操作,比如'Timeout'。 –

相關問題