当前位置: 首页 > 编程语言 > C#

使用FromAsyncPattern进行单元测试分享

时间:2023-04-10 23:07:08 C#

使用FromAsyncPattern进行单元测试ReactiveExtensions有一个性感的小钩子来简化调用异步方法:varfunc=Observable.FromAsyncPattern(myWcfService.BeginDoStuff,myWcfService.EndDoStuff);func(inData).ObserveOnDispatcher().Subscribe(x=>Foo(x));我在WPF项目中使用它,它在运行时运行良好。不幸的是,在尝试将此技术与单元测试方法结合使用时,我遇到了随机失败。每5次执行包含此代码的测试中大约有3次失败。这是一个示例测试(使用Rhino/unity自动模拟容器实现):[TestMethod()]publicvoidSomeTest(){//arrangevarcontainer=GetAutoMockingContainer();container.Resolve().Expect(x=>x.BeginDoStuff(null,null,null)).IgnoreArguments().Do(newFunc((inData,asyncCallback,state)=>{returnnewCompletedAsyncResult(asyncCallback,state);}));container.Resolve().Expect(x=>x.EndDoStuff(null)).IgnoreArguments().Do(newFunc((ar)=>{returnsomeMockData;}));//动作vartarget=CreateTestSubject(container);target.DoMethodThatInvokesService();//为高于后台优先级的所有内容运行调度程序Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background,newAction(()=>{}));//断言Assert.IsTrue(我的操作按预期运行);我看到问题是我指定在异步操作完成时运行的代码(在本例中为Foo(x))从未被调用。我可以通过在Foo中设置断点并观察它们永远不会到达来验证这一点。此外,我可以在调用DoMethodThatInvokesService(启动异步调用)后强制延迟很长时间,但代码仍然没有运行。我知道调用Rx框架的那行代码被调用了。我尝试过的其他事情:这将我的失败率提高到五分之一,但它们仍然存在。我最终解决了这个问题(即不使用Rx),但我认为这并不理想。如果过去有人遇到过这个问题并找到了解决方案,我很想听听。更新:我还在Rx论坛上发帖说他们将为即将发布的版本包含一个测试调度程序。一旦可用,这可能是最终的解决方案。问题是由ObserveOnDispatcher调度的调用的异步性质引起的。您不能保证它们在测试结束时全部完成。所以你需要在你的控制下安排。如何将调度程序注入您的班级?然后,不调用ObserveOnDispatcher,而是调用ObserveOnDispatcher,传入注入的IScheduler实现。在运行时,您将注入DispatcherScheduler,但在您的测试中,您将注入一个伪造的调度程序,该调度程序将对给定的所有操作进行排队,并在您的测试控制的时间运行它们。如果你不喜欢在你使用Rx的地方注入调度器的想法,那么创建你自己的扩展方法怎么样(未经测试的代码):(此IObservable源){if(UISafeScheduler==null){thrownewInvalidOperation("UISafeScheduler尚未初始化");}returnsource.ObserveOn(UISafeScheduler);然后在运行时,使用DispatcherScheduler进行初始化,并在测试中使用您的假调度程序对其进行初始化。问题是MSTest.exe运行Dispatcher(即Dispatcher.Current!=null),因此ObserveOnDispatcher工作正常。但是,这个Dispatcher什么都不做!(关于忽略排队的调度程序项目)您编写的任何明确使用Schedule.Dispatcher的代码都是不可测试的ReactiveUI/RxApp.cs#L99我们基本上设置了一个定义默认调度程序的全局变量,然后我们尝试检测何时进入测试运行程序。然后,在我们实现IObservable的类中,都带有IScheduler参数,其默认值最终将成为全局默认调度程序。我本可以做得更好,但这对我有用,并使ViewModel代码再次可测试。以上就是C#学习教程的全部内容:使用FromAsyncPattern进行单元测试。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右边联系管理员删除。如需转载请注明出处: