如何对使用定时器的Rx运算符进行单元测试?

Jam*_*Hay 6 unit-testing system.reactive

有许多基于计时器的运算符,虽然我没有具体的例子,但我认为创建使用计时器的新运算符很常见.那么你将如何编写一个同步运行这些运算符的测试?

作为一个例子,我怎样才能对像BufferWithTime这样的运算符进行单元测试呢?

Ric*_*lay 8

最容易进行测试的方法是使用TestScheduler:

var source = new Subject<int>();
var scheduler = new TestScheduler();

var outputValues = new List<IList<int>>();

source
    .BufferWithTime(TimeSpan.FromTicks(500), scheduler)
    .Subscribe(x => outputValues.Add(x));

scheduler.RunTo(1);
source.OnNext(1);

scheduler.RunTo(100);
source.OnNext(2);

scheduler.RunTo(200);
source.OnNext(3);

scheduler.RunTo(501);
source.OnNext(4);

scheduler.RunTo(1001);

Assert.AreEqual(2, outputValues.Count);
Assert.AreEqual(3, outputValues[0].Count);
Assert.AreEqual(1, outputValues[1].Count);
Run Code Online (Sandbox Code Playgroud)

此外,您还可以使用一组类型System.Reactive.Testing.dll,这使得事情变得更加容易,但依赖于Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll依赖性System.Web.dll(在客户端配置文件中不可用).

// using System.Reactive.Testing;
// using System.Reactive.Testing.Mocks;

var scheduler = new TestScheduler();

var source = scheduler.CreateColdObservable(
    new Recorded<Notification<int>>(0, new Notification<int>.OnNext(1)),
    new Recorded<Notification<int>>(100, new Notification<int>.OnNext(2)),
    new Recorded<Notification<int>>(400, new Notification<int>.OnNext(3)),
    new Recorded<Notification<int>>(500, new Notification<int>.OnNext(4))
    )
    .BufferWithTime(TimeSpan.FromTicks(500), scheduler);

var observer = new MockObserver<IList<int>>(scheduler);

source.Subscribe(observer);

scheduler.RunTo(1001);

Assert.AreEqual(2, observer.Count);
Assert.AreEqual(3, observer[0].Value.Value.Count);
Assert.AreEqual(1, observer[1].Value.Value.Count);
Run Code Online (Sandbox Code Playgroud)

  • 要在使用System.Reactive.Testing时获得测试的良好可读性,请使用您自己的测试帮助程序类,如下所述:http://blogs.msdn.com/b/jeffva/archive/2010/08/27/testing-rx的.aspx (4认同)