1

我努力讓我的頭圍繞如何使這個測試通過:測試相結合Rx和TPL

[Fact] 
public void scheduler_test() 
{ 
    var scheduler = new TestScheduler(); 
    var value1Set = false; 
    var value2Set = false; 

    Observable.Return(true) 
     .Delay(TimeSpan.FromMilliseconds(100), scheduler) 
     .Subscribe(_ => value1Set = true); 

    Observable.Return(true) 
     .Delay(TimeSpan.FromMilliseconds(100), scheduler) 
     .Subscribe(async _ => 
     { 
      await Task 
       .Delay(500) 
       .ContinueWith(__ => value2Set = true); 
     }); 

    Assert.False(value1Set); 
    Assert.False(value2Set); 
    scheduler.AdvanceBy(TimeSpan.FromMilliseconds(500).Ticks); 
    Assert.True(value1Set); 
    Assert.True(value2Set); 
} 

它目前無法對最終的說法。我認爲async訂閱會阻止,直到等待完成Task,但似乎並非如此。

任何人都可以解釋爲什麼這不起作用,以及應該如何去測試這樣的組合場景?

回答

2

您不能在TestScheduler中使用TPL。 Task.Delay將等待500 實際毫秒,而不是模擬的。您需要使用Delay的Rx兼容版本,例如Observable.Timer

在一個不相關的音符,不要使用在Subscribe異步方法,寫這樣的事情,而不是:

Observable.Return(true) 
    .Delay(TimeSpan.FromMilliseconds(100), scheduler) 
    .SelectMany(async _ => await Task.Delay(500)) 
    .Subscribe(
    { 
     value2Set = true; 
    }); 
+0

感謝保羅,但表現出完全一樣的行爲。也就是說,由於延遲還沒有完成,所以'value2Set'在最後的斷言中是'false'。基本上,我希望被動管道在它認爲自己「處理好」之前等待TPL任務完成。 –

+0

我的評論的第二部分是更多的代碼審查,它仍然不會工作,因爲我上面提到的 –

+0

順便說一下,我可以通過更改訂閱非異步並調用'Task(Wait)()',但我猜這也是一個壞主意,因爲阻塞線程和所有。 –