Thursday, December 22, 2011

Advancing the time with TestScheduler in Reactive Extensions.

In this post I'm going to show you how you can programmatically advance the time with the test scheduler so you don't have to wait 5 days for an event in your test environment. First we will prepare a testable cold observable. It will schedule us 4 OnNext notifications every 100 virtual ticks and finally after 500 ticks an OnCompleted notification kind.
var testScheduler = new TestScheduler();            
    
var records = new Recorded<Notification<int>>[] {
    ReactiveTest.OnNext(100, 1),
    ReactiveTest.OnNext(200, 2),
    ReactiveTest.OnNext(300, 3),
    ReactiveTest.OnNext(400, 4),
    ReactiveTest.OnCompleted<int>(500)
};

ITestableObserver<int> testableObserver = 
    testScheduler.CreateObserver<int>();
    
ITestableObservable<int> testableObservable = 
    testScheduler.CreateColdObservable(records);

IDisposable d = testableObservable.Subscribe(testableObserver)
Now you can use AdvanceBy which advances the test schedulers Clock by this relative time (testScheduler.Clock+time) and runs all the scheduled work within it. You can also use the AdvanceTo method to run all scheduled items up to this absolute time and again advance the schedulers Clock to this point. The Start method runs the remaining work from the actual Clock time.
int subscrCount = testableObservable.Subscriptions.Count();
Console.WriteLine("Number of subscriptions to the test observable: {0}"
                  , subscrCount);

testScheduler.AdvanceBy(200);
Console.WriteLine("Messages sent({0}) until {1}"
                  , testableObserver.Messages.Count 
                  , testScheduler.Clock);

testScheduler.AdvanceTo(400);
Console.WriteLine("Messages sent({0}) until {1}"
                  , testableObserver.Messages.Count 
                  , testScheduler.Clock);

testScheduler.Start();
Console.WriteLine("Messages sent({0}) until {1}"
                  , testableObserver.Messages.Count 
                  , testScheduler.Clock);
                      
foreach (var message in testableObserver.Messages)
{
    Console.WriteLine("Value {0} at {1}", message.Value, message.Time);
}
At the end you can check that all scheduled items were run and sent to the mock observer.
================
Number of subscriptions to the test observable: 1
Messages sent(2) until 200
Messages sent(4) until 400
Messages sent(5) until 500
Value OnNext(1) at 100
Value OnNext(2) at 200
Value OnNext(3) at 300
Value OnNext(4) at 400
Value OnCompleted() at 500

================

No comments:

Post a Comment