Windows runtime 使用Rx RTM进行可观测命令和单元测试

Windows runtime 使用Rx RTM进行可观测命令和单元测试,windows-runtime,system.reactive,reactiveui,Windows Runtime,System.reactive,Reactiveui,我已经将代码移植到WinRT和Rx的RTM版本。我在ViewModels中使用ReactiveUI。在移植代码之前,我的单元测试运行没有问题,但现在我有了一个奇怪的行为 以下是测试: var sut = new MyViewModel(); myViewModel.MyCommand.Execute(null) //ReactiveAsyncCommand Assert.AreEqaul(0, sut.Collection.Count) 如果我一步一步地调试测试,断言不是失败的,但是使用测试运

我已经将代码移植到WinRT和Rx的RTM版本。我在ViewModels中使用ReactiveUI。在移植代码之前,我的单元测试运行没有问题,但现在我有了一个奇怪的行为

以下是测试:

var sut = new MyViewModel();
myViewModel.MyCommand.Execute(null) //ReactiveAsyncCommand
Assert.AreEqaul(0, sut.Collection.Count)
如果我一步一步地调试测试,断言不是失败的,但是使用测试运行程序它失败了

断言的集合由订阅命令的方法修改:

MyCommand.RegisterAsyncTask(_ => DoWork())
            .ObserveOn(SynchronizationContext.Current)
            .Subscribe(MethodModifyingCollection);

在将代码移动到RTM之前,该代码正在工作。我还试图删除
观测值,并在断言之前添加
等待任务.Delay()
,但没有成功。

您的问题是MSTest单元测试有一个默认的
同步上下文。因此,
ObserveOn
ReactiveAsyncCommand
将封送到线程池,而不是WPF上下文。这会导致竞争条件

您的第一个也是最好的选择是

另一个选项是等待一些完成信号(并确保您的测试方法是
异步任务
,而不是
异步无效

否则,如果您只需要一个
SynchronizationContext
,您可以使用在自己的
SynchronizationContext
中执行测试


最后,如果您有任何直接使用
Dispatcher
而不是
SynchronizationContext
的代码,您可以从异步CTP下载中使用
WpfContext

您的问题是MSTest单元测试有一个默认的
SynchronizationContext
。因此,
ObserveOn
ReactiveAsyncCommand
将封送到线程池,而不是WPF上下文。这会导致竞争条件

您的第一个也是最好的选择是

另一个选项是等待一些完成信号(并确保您的测试方法是
异步任务
,而不是
异步无效

否则,如果您只需要一个
SynchronizationContext
,您可以使用在自己的
SynchronizationContext
中执行测试


最后,如果您有任何直接使用
Dispatcher
而不是
SynchronizationContext
的代码,您可以使用异步CTP下载的
WpfContext

Steven得到了正确的答案,但缺少一些RxUI特定的东西。这肯定与测试运行程序中的调度有关,但原因是WinRT版本的ReactiveUI目前无法正确检测它是否在测试运行程序中

目前的愚蠢解决方法是在所有测试的顶部设置此选项:

RxApp.DeferredScheduler = Scheduler.CurrentThread;

不要在每次测试中都使用TestScheduler,这样做太过分了,实际上与某些类型的测试不兼容。TestScheduler适用于模拟时间流逝的测试。

Steven得到了正确的答案,但缺少一些RxUI特有的东西。这肯定与测试运行程序中的调度有关,但原因是WinRT版本的ReactiveUI目前无法正确检测它是否在测试运行程序中

目前的愚蠢解决方法是在所有测试的顶部设置此选项:

RxApp.DeferredScheduler = Scheduler.CurrentThread;

不要在每次测试中都使用TestScheduler,这样做太过分了,实际上与某些类型的测试不兼容。TestScheduler适用于模拟时间流逝的测试。

感谢Stephen的回答。我明天要测试它,但我在WinRT上,所以WPF相关的解决方案不是一个选项。TestScheduler似乎很有前途。
WpfContext
-尽管名称不同-只是使用了
Dispatcher
,我相信它对SL有效,所以我希望它对WinRT也有效。谢谢Stephen的回答。我明天要测试它,但我在WinRT上,所以WPF相关的解决方案不是一个选项。TestScheduler似乎很有前途。
WpfContext
——尽管名称不同——只是使用了
Dispatcher
,我相信它对SL有效,所以我希望它也能对WinRT有效。