2013-04-24 49 views
3

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

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。

我很清楚自己做错了什么 - 但没有弄清楚我做错了什么。

回答

0

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

在运行时,你只会默认为你的情况下的敏感默认值。

+0

嗯,这可能工作。但是我真的需要开始将IScheduler暴露给我的代码吗?我不希望IObservable的订户必须知道明确说明他们想要使用什么调度程序等。 – 2013-04-25 09:22:01

+0

如果你看看Rx方法,它们中的很多会有重载,它们会带一个'IScheduler',所以在结束这是没有任何不同。 – 2013-04-25 20:33:16

+0

嗯,是的 - 但文档也说,SubscribeOn应该很少使用。 – 2013-04-26 07:21:50