c# – 使用Reactive Extensions对事件进行单元测试
我正在使用
Reactive Extensions for .NET (Rx)将事件公开为IObservable< T>.我想创建一个单元测试,我断言特定事件被触发.这是我要测试的类的简化版本:
public sealed class ClassUnderTest : IDisposable { Subject<Unit> subject = new Subject<Unit>(); public IObservable<Unit> SomethingHappened { get { return this.subject.AsObservable(); } } public void DoSomething() { this.subject.OnNext(new Unit()); } public void Dispose() { this.subject.OnCompleted(); } } 显然我的真正课程更复杂.我的目标是验证对被测试类执行某些操作会导致在IObservable上发出一系列事件.幸运的是,我想要测试的类实现IDisposable并在处理对象时调用OnCompleted使得测试更加容易. 这是我测试的方式: // Arrange var classUnderTest = new ClassUnderTest(); var eventFired = false; classUnderTest.SomethingHappened.Subscribe(_ => eventFired = true); // Act classUnderTest.DoSomething(); // Assert Assert.IsTrue(eventFired); 使用变量来确定事件是否被触发也不是太糟糕,但在更复杂的场景中,我可能想要验证是否触发了特定的事件序列.如果不简单地在变量中记录事件然后对变量进行断言,这是否可能?能够使用流畅的类LINQ语法在IObservable上进行断言有望使测试更具可读性. 解决方法
此答案已更新至现已发布的Rx版本1.0.
官方文档仍然很少,但MSDN上的Testing and Debugging Observable Sequences是一个很好的起点. 测试类应该从Microsoft.Reactive.Testing命名空间中的 TestScheduler.Schedule方法可用于在虚拟时间内在某些点(滴答)排队活动.测试由TestScheduler.Start执行.这将返回ITestableObserver< T>例如,可以使用ReactiveAssert类来断言. public class Fixture : ReactiveTest { public void SomethingHappenedTest() { // Arrange var scheduler = new TestScheduler(); var classUnderTest = new ClassUnderTest(); // Act scheduler.Schedule(TimeSpan.FromTicks(20),() => classUnderTest.DoSomething()); var actual = scheduler.Start( () => classUnderTest.SomethingHappened,created: 0,subscribed: 10,disposed: 100 ); // Assert var expected = new[] { OnNext(20,new Unit()) }; ReactiveAssert.AreElementsEqual(expected,actual.Messages); } } TestScheduler.Schedule用于在时间20安排对DoSomething的调用(以滴答为单位). 然后TestScheduler.Start用于对可观察的SomethingHappened执行实际测试.订阅的生命周期由调用的参数控制(再次以刻度形式测量). 最后,ReactiveAssert.AreElementsEqual用于验证OnNext是否按预期在时间20调用. 测试验证调用DoSomething会立即触发可观察的SomethingHappened. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- Cocos2d-x 布局Layout , VBox,HBox可以互相嵌套
- 基础学习笔记之opencv(3):haartraining生成.xml文件过程
- C#入门教程之ListBox控件使用方法
- xml – 描述和内容之间的区别:RSS2中的编码标签
- cocos2d-x-3.3-024-仿微信飞机大战-如何引爆炸弹-实现范围攻
- 解决vue-router进行build无法正常显示路由页面的问题
- Oracle 12cR1 RAC 在VMware Workstation上安装(中)―图形界
- ruby – 何时使用隐式或显式代码块
- jQuery.getJSON调用ASP.NET方法
- dart – Flutter:设置AppBar的高度