测试结合Rx和TPL

时间:2014-03-04 01:34:26

标签: .net unit-testing task-parallel-library system.reactive scheduler

我正在努力探讨如何通过测试:

[Fact]
public void scheduler_test()
{
    var scheduler = new TestScheduler();
    var value1Set = false;
    var value2Set = false;

    Observable.Return(true)
        .Delay(TimeSpan.FromMilliseconds(100), scheduler)
        .Subscribe(_ => value1Set = true);

    Observable.Return(true)
        .Delay(TimeSpan.FromMilliseconds(100), scheduler)
        .Subscribe(async _ =>
        {
            await Task
                .Delay(500)
                .ContinueWith(__ => value2Set = true);
        });

    Assert.False(value1Set);
    Assert.False(value2Set);
    scheduler.AdvanceBy(TimeSpan.FromMilliseconds(500).Ticks);
    Assert.True(value1Set);
    Assert.True(value2Set);
}

目前最终的断言失败了。我认为async订阅会在等待Task完成之前阻止,但情况似乎并非如此。

任何人都可以解释为什么这不起作用,以及应该如何测试这样的组合场景?

1 个答案:

答案 0 :(得分:2)

您不能将TPL与TestScheduler一起使用。 Task.Delay将等待500 real 毫秒,而不是模拟的。您需要使用与Rx兼容的Delay版本,例如Observable.Timer

在不相关的说明中,不要在Subscribe中使用异步方法,而是写下这样的内容:

Observable.Return(true)
    .Delay(TimeSpan.FromMilliseconds(100), scheduler)
    .SelectMany(async _ => await Task.Delay(500))
    .Subscribe(
    {
        value2Set = true;
    });