I have the following class which basically subscribes to an int observable and multiplies the value by 2. For reality purposes I added a Thread.Sleep to simulate a heavy processing.
public class WorkingClass
{
private BlockingCollection<int> _collection = new BlockingCollection<int>(1);
public WorkingClass(IObservable<int> rawValues)
{
rawValues.Subscribe(x => _collection.Add(x));
}
public IObservable<int> ProcessedValues()
{
return Observable.Create<int>(observer =>
{
while (true)
{
int value;
try
{
value = _collection.Take();
}
catch (Exception ex)
{
observer.OnError(ex);
break;
}
Thread.Sleep(1000); //Simulate long work
observer.OnNext(value * 2);
}
return Disposable.Empty;
});
}
}
I'm having trouble testing it, in the following test I just want to assert that if the source stream emits the value 1 the SUT will emit the value 2:
[Test]
public void SimpleTest()
{
var sourceValuesScheduler = new TestScheduler();
var newThreadScheduler = new TestScheduler();
var source = sourceValuesScheduler.CreateHotObservable(
new Recorded<Notification<int>>(1000, Notification.CreateOnNext(1)));
var sut = new WorkingClass(source);
var observer = sourceValuesScheduler.CreateObserver<int>();
sut.ProcessedValues()
.SubscribeOn(newThreadScheduler) //The cold part (i.e, the while loop) of the ProcessedValues Observable should run in a different thread
.Subscribe(observer);
sourceValuesScheduler.AdvanceTo(1000);
observer.Messages.AssertEqual(new Recorded<Notification<int>>(1000, Notification.CreateOnNext(2)));
}
If I run this test the assert fails because the newThreadScheduler was never started and consequently the ProcessedValues observable was never created. If I do this:
sourceValuesScheduler.AdvanceTo(1000);
newThreadScheduler.AdvanceTo(1000);
It doesn't work either because the newThreadScheduler uses the same Thread of the sourceValuesScheduler so the test will be hanging right after the processed value is emmited, at the line:
value = _collection.Take();
Is there a way we can have multiple TestSchedulers running on different threads? Otherwise how can I test classes like this?