我有一个测试代码示例:

    [Fact]
    public void Should_only_contain_most_recent() {
        var window = TimeSpan.FromMilliseconds(200);
        var results = new ReplaySubject<long>(window);
        results.OnNext(1);
        results.OnNext(2);
        System.Threading.Thread.Sleep(50);
        results.OnNext(3);
        System.Threading.Thread.Sleep(50);
        results.OnNext(4);
        System.Threading.Thread.Sleep(200);
        results.OnNext(5);
        results.OnCompleted();
        var items = results.ToEnumerable();
        Assert.True(items.SequenceEqual(new long [] { 5 }));
    }


我想变成使用Microsoft.Reactive.Testing包中的TestScheduler,因为我想摆脱这里的沉睡。

我已经尝试做类似的事情。

    [Fact]
    public void Should_only_contain_most_recent() {
        var scheduler = new TestScheduler();
        var window = TimeSpan.FromMilliseconds(200);
        var results = new ReplaySubject<long>(window /* Never finishes when add the scheduler here.*/);
        results.OnNext(1);
        results.OnNext(2);
        scheduler.Schedule(TimeSpan.FromMilliseconds(50), () => results.OnNext(3));
        scheduler.Schedule(TimeSpan.FromMilliseconds(50), () => results.OnNext(4));
        scheduler.Schedule(TimeSpan.FromMilliseconds(200), () => results.OnNext(5));
        scheduler.Schedule(TimeSpan.FromMilliseconds(210), results.OnCompleted);
        scheduler.Start();

        var items = results.ToEnumerable();
        Assert.True(items.SequenceEqual(new long[] { 5 }));
    }


但是我缺少了一些东西。

最佳答案

大概您正在尝试测试ReplaySubject的重播行为。问题是您需要两次启动TestScheduler。它仅在执行所有计划的事件之前一直运行-但是我们需要在没有任何订阅服务器的情况下加载ReplaySubject,以便它具有将要重播的事件-然后在订阅服务器连接后再次运行调度程序。

这是编写此测试的惯用方式:

首先,我为source设置了我们需要的事件。通过从ReactiveTest派生测试类,您可以利用OnXXX helper方法更轻松地创建源事件。

准备好源流之后,我们可以预订ReplaySubject并在Start上调用TestScheduler。这将使虚拟时间一直运行到最后安排的事件(T = 300ms)-我通过转储超时来演示这一点。

现在,我们使用TestSchedulerCreateObserver方法为结果创建记录器,并将其预订为ReplaySubject

现在,我们再次启动TestScheduler-从T = 300ms开始运行时钟,直到刷新新创建的计划事件。这些是ReplaySubject需要重播的事件-200ms窗口内的事件。请注意,这些将在T = 300ms + 1个滴答声,+ 2个滴答声和+ 3个滴答声时发出-这是因为TestScheduler具有1个滴答声分辨率。

这是代码:

public class MyTests : ReactiveTest
{
    [Fact]
    public void Should_only_contain_most_recent()
    {
        var scheduler = new TestScheduler();

        var source = scheduler.CreateHotObservable(
            OnNext(0, 1),
            OnNext(0, 2),
            OnNext(TimeSpan.FromMilliseconds(50).Ticks, 3),
            OnNext(TimeSpan.FromMilliseconds(100).Ticks, 4),
            OnNext(TimeSpan.FromMilliseconds(300).Ticks, 5),
            OnCompleted(TimeSpan.FromMilliseconds(300).Ticks, witness: 0));

        var replaySubject = new ReplaySubject<int>(
            TimeSpan.FromMilliseconds(200), scheduler);

        source.Subscribe(replaySubject);

        scheduler.Start();

        /* the test scheduler is now at 300 milliseconds
            * and the ReplaySubject is loaded */
        Console.WriteLine(scheduler.Now.Ticks);

        var results = scheduler.CreateObserver<int>();
        replaySubject.Subscribe(results);

        /* run the scheduler on to flush the events from the ReplaySubject */
        scheduler.Start();

        results.Messages.AssertEqual(
            OnNext(TimeSpan.FromMilliseconds(300).Ticks + 1, 4),
            OnNext(TimeSpan.FromMilliseconds(300).Ticks + 2, 5),
            OnCompleted(TimeSpan.FromMilliseconds(300).Ticks + 3, witness: 0));
    }
}

关于c# - 如何在窗口ReplaySubject时间内使用TestScheduler,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25102256/

10-08 22:37