测试观测量时如何使用Task.Run虚拟时间,我有以下功能我想测试与无扩展
/// Items are processed asynchronously via fn as they arrive. However
/// if an item arrives before the last asynchronous operation has
/// completed then the cancellation token passed to fn will be
/// triggered enabling the task to be canceled in a best effort
/// way.
public static IObservable<U> SelectWithCancellation<T, U>
(this IObservable<T> This
, Func<CancellationToken, T, Task<U>> fn
)
{
return This
.Select(v=>Observable.FromAsync(token=>fn(token, v)))
.Switch();
}
我要测试它,最好的我已经能够拿出 工作原理如下。首先,我创建一个长时间运行的任务, 可以取消
public Task<string> JobTask
(CancellationToken token
, string input
)
{
return Task.Factory.StartNew(() =>
{
if (input == "C" || input == "E")
{
while (!token.IsCancellationRequested) ;
}
return input;
}
);
}
,然后我测试,它可以真正起作用
public class SelectWithCancelationSpec : ReactiveTest
{
TestScheduler _Scheduler = new TestScheduler();
[Fact]
public void ShouldWork()
{
var o = _Scheduler.CreateHotObservable
(OnNext(100, "A")
, OnNext(200, "B")
, OnNext(300, "C")
, OnNext(400, "D")
, OnNext(500, "E")
, OnNext(500, "F")
);
List<string> actual = new List<string>();
o
.SelectWithCancellation(JobTask)
.Subscribe(v => actual.Add(v));
var delay = 100;
_Scheduler.AdvanceTo(150);
Thread.Sleep(delay);
_Scheduler.AdvanceTo(250);
Thread.Sleep(delay);
_Scheduler.AdvanceTo(350);
Thread.Sleep(delay);
_Scheduler.AdvanceTo(450);
Thread.Sleep(delay);
_Scheduler.AdvanceTo(550);
Thread.Sleep(delay);
_Scheduler.AdvanceTo(650);
var expected = new[] { "A", "B", "D", "F" };
actual
.ShouldBeEquivalentTo(expected);
}
}
的问题是,我不得不引进real time
到 测试。这是因为我的模拟JobTask运行在线程池的真实 线程上,并且不考虑测试调度程序的虚拟时间 。如果我不把延迟 置于AdvanceTo
调用之间,会发生什么情况是因为JobTask需要太长的时间来处理,所以我在测试中放弃了多于 的消息。
问题是。我如何创建一个尊重 虚拟时间的JobTask,并允许我测试是否可以成功删除 预期的消息。