基本的RX TestScheduler时序

时间:2013-04-24 20:09:41

标签: c# unit-testing system.reactive

我正在使用RX做一些(非常基本的)事件订阅: -

public void StartListening(IObservable<Item> observable)
{
   subscription = observable
      .Buffer(TimeSpan.FromSeconds(5))
      .Where(Enumerable.Any)
      .Subscribe(events => service.DoStuffInBatch(events));
}

现在我想要的是一组单元测试,证明了这种方法的行为。例如: -

  • 如果我得到数据但时间还没有超过5秒,我们从不打电话给DoStuffInBatch。
  • 如果我获得数据并且时间已经过了5秒,我会用数据调用DoStuffInBatch。
  • 如果我没有获得数据并且时间已经过了5秒,我就不会调用DoStuffInBatch。
  • 如果我通过两个窗口获取数据,例如一些在3秒,一些在8秒,我打两次电话给DoStuffInBatch。

我一直在阅读巴特所提出的所有例子(例如http://blogs.msdn.com/b/rxteam/archive/2012/06/14/testing-rx-queries-using-virtual-time-scheduling.aspx),但我真的很难接受我的测试。这是一个例子: -

[Test]
public void StartListening_SomeDataAndBatchTimeHasNotPassed_DoesNotDoStuffInBatch()
{
    var scheduler = new TestScheduler();

    // Act - call the class under test, supplying a set of dummy data on the test scheduler
    listener.StartListening(GenerateTestData(5).ToObservable(scheduler));

    // Move the scheduler forward by one second
    scheduler.AdvanceBy(TimeSpan.FromSeconds(1).Ticks);

    // Assert that we never called the service as we haven't yet advanced 5 seconds
    Mock.Assert(() => mockService.DoStuffInBatch(null), Args.Ignore(), Occurs.Never());
}

但是,此测试失败。一旦我调用AdvanceBy,订阅就会触发并调用DoStuffInBatch。

我显然做错了什么 - 但是我不知道我做错了什么。

1 个答案:

答案 0 :(得分:0)

也许您可以尝试将IScheduler参数传递给StartListening方法,并使用它将TestScheduler实例传递给.Buffer(),或传递给.SubscribeOn() ?

在运行时,您只需默认为您的案例的敏感默认值。