2012-09-20 65 views
2

我一直在閱讀這樣的:Testing Rx Queries using Virtual Time Scheduling如何進行TestScheduler在無擴展v2的工作

我到了部分「使用單元測試項目」(大約一半下來的頁面),並沒有嘗試過自己(使用VS2012 & MSTest的)但我的結果與文檔中的不一樣。具體來說,我的斷言失敗了。

這裏是我的測試代碼:

[TestMethod] 
public void TestMethod1() 
{ 
    var scheduler = new TestScheduler(); 

    var xs = scheduler.CreateColdObservable(
     OnNext(10, 42), 
     OnCompleted<int>(20)); 

    var observer1 = scheduler.CreateObserver<int>(); 
    scheduler.Schedule(TimeSpan.FromTicks(190), 
         (s, t) => xs.Subscribe(observer1)); 

    var observer2 = scheduler.CreateObserver<int>(); 
    scheduler.Schedule(TimeSpan.FromTicks(220), 
         (s, t) => xs.Subscribe(observer2)); 

    scheduler.Start(); 

    observer1.Messages.AssertEqual(
     OnNext(200, 42), 
     OnCompleted<int>(210)); 

    observer2.Messages.AssertEqual(
     OnNext(230, 42), 
     OnCompleted<int>(240)); 
} 

一個變化我不得不做出的是:

scheduler.Schedule(TimeSpan.FromTicks(190), 
        () => xs.Subscribe(observer1)); 

變成了:

scheduler.Schedule(TimeSpan.FromTicks(190), 
        (s, t) => xs.Subscribe(observer1)); 

老實說我不知道把握這種變化的影響(我從來沒有用C#編碼那麼久!)。

而且這裏的結果:

Assert.Fail failed. 
Expected: [OnNext(42)@200, OnCompleted()@210] 
Actual..: [OnNext(42)@11, OnCompleted()@21] 

我的理解是,我創建一個冷觀察到的,將返回10日刻度值42和20日蜱序列完成的方式。然後創建和觀察者訂閱這個可觀察的事件,表明我想要在190時刻開始計劃。因此,在時間戳200(190 + 10)處測試值42,並在時鐘210處完成時間。然而,我得到時刻11和21個。

該文檔基於V2的預RTM,因此我不確定TestScheduler的行爲是否在RTM中發生了更改,或者我是否在某處出錯。如果有人能解釋發生了什麼,我會很感激。

+0

快速查看你的代碼,我同意你所得到的是令人困惑的。根據我對TestSchedulers工作原理的理解,測試看起來是正確的,所以我不確定爲什麼你會得到失敗的測試。 –

回答

8

看來您已經忘記導入您想要使用定義Schedule超載的System.Reactive.Concurrency命名空間。這就解釋了爲什麼你要更改代碼 - 方便擴展方法可能沒有露面:

using System.Reactive.Concurrency; 

你使用計劃的過載是所使用的即時調度的一個,傳遞時間跨度值在TSTATE參數:立即在調度開始於時間0每個工作項目增加時鐘(沒有事件可以測試調度同時發生的,它模仿一個

public IDisposable Schedule<TState>(TState state, Func<IScheduler, TState, IDisposable> action) 

因此,訂閱XS將開展單線程執行),因此您在時間1看到一個序列訂閱,在時間2看到另一個序列訂閱。

一個可能的解決辦法是使用以下命令:

var observer1 = scheduler.CreateObserver<int>(); 
scheduler.ScheduleAbsolute(190,() => xs.Subscribe(observer1)); 

var observer2 = scheduler.CreateObserver<int>(); 
scheduler.ScheduleAbsolute(220,() => xs.Subscribe(observer2)); 

確保導入System.Reactive.Concurrency命名空間來找到這些過載。您也可以在這裏使用ScheduleRelative,因爲調度程序尚未啓動,到期時間將爲當前調度程序的時鐘值(= 0)加上指定的相對時長。

或者,您也可以使用DateTimeOffset或TimeSpan重載通過IScheduler API表面。只要小心選擇合適的過載(使用F12 - 進入定義 - 查看您選擇的超載量)。

var observer1 = scheduler.CreateObserver<int>(); 
scheduler.Schedule(TimeSpan.FromTicks(190),() => xs.Subscribe(observer1)); 

var observer2 = scheduler.CreateObserver<int>(); 
scheduler.Schedule(TimeSpan.FromTicks(220),() => xs.Subscribe(observer2)); 

同樣,確保用using指令導入System.Reactive.Concurrency命名空間中才能看到此重載:-)。

+0

我在'TestScheduler.Schedule'方法上也遇到了一個編譯器錯誤:'沒有爲方法'Schedule'重載'需要1個參數。' 一旦我添加'using System.Reactive.Concurrency;'問題就解決了。 – Philippe