2013-04-24 52 views
3

我使用RX做一些(非常基本的)事件訂閱: -基本RX TestScheduler時間

public void StartListening(IObservable<Item> observable) 
{ 
    subscription = observable 
     .Buffer(TimeSpan.FromSeconds(5)) 
     .Where(Enumerable.Any) 
     .Subscribe(events => service.DoStuffInBatch(events)); 
} 

現在,我要的是一組單元測試,證明了該方法的行爲。例如: -

  • 如果我得到的數據,但時間尚未5秒,我們從來沒有調用DoStuffInBatch。
  • 如果我得到的數據和時間已經過去了5秒鐘,我用數據調用了DoStuffInBatch。
  • 如果我沒有得到數據,並且時間已經超過5秒,我不會調用DoStuffInBatch。
  • 如果我通過兩個窗口獲取數據,例如一些在3秒鐘,一些在8秒鐘,我做了兩次調用DoStuffInBatch。

我一直在閱讀巴特所推出的所有例子(例如http://blogs.msdn.com/b/rxteam/archive/2012/06/14/testing-rx-queries-using-virtual-time-scheduling.aspx),但我真的在爲我的測試掙扎。以下是一個示例: -

[Test] 
public void StartListening_SomeDataAndBatchTimeHasNotPassed_DoesNotDoStuffInBatch() 
{ 
    var scheduler = new TestScheduler(); 

    // Act - call the class under test, supplying a set of dummy data on the test scheduler 
    listener.StartListening(GenerateTestData(5).ToObservable(scheduler)); 

    // Move the scheduler forward by one second 
    scheduler.AdvanceBy(TimeSpan.FromSeconds(1).Ticks); 

    // Assert that we never called the service as we haven't yet advanced 5 seconds 
    Mock.Assert(() => mockService.DoStuffInBatch(null), Args.Ignore(), Occurs.Never()); 
} 

但是,此測試失敗。只要我打電話給AdvanceBy,訂閱就會觸發並調用DoStuffInBatch。

我很清楚自己做錯了什麼 - 但沒有弄清楚我做錯了什麼。

回答

0

也許你可以嘗試將IScheduler參數傳遞給StartListening方法,並使用它將TestScheduler實例傳遞給.Buffer()或調用.SubscribeOn()?

在運行時,你只會默認爲你的情況下的敏感默認值。

+0

嗯,這可能工作。但是我真的需要開始將IScheduler暴露給我的代碼嗎?我不希望IObservable的訂戶必須知道明確說明他們想要使用什麼調度程序等。 – 2013-04-25 09:22:01

+0

如果你看看Rx方法,它們中的很多會有重載,它們會帶一個'IScheduler',所以在結束這是沒有任何不同。 – 2013-04-25 20:33:16

+0

嗯,是的 - 但文檔也說,SubscribeOn應該很少使用。 – 2013-04-26 07:21:50