0

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に移動する前に機能していました。また、を削除して、アサートObserveOnの前に追加しようとしましたがawait Task.Delay()、成功しませんでした。

4

2 に答える 2

3

スティーブンは正しい答えを得ましたが、RxUI固有のものがいくつか欠けています。これは間違いなくテストランナーでのスケジューリングに関連していますが、その理由は、ReactiveUIのWinRTバージョンが現時点でテストランナーにあるかどうかを正しく検出できないためです。

今のところ、ばかげた回避策は、これをすべてのテストの先頭に設定することです。

RxApp.DeferredScheduler = Scheduler.CurrentThread;

すべてのテストにTestSchedulerを使用しないでください。それはやり過ぎであり、実際には特定の種類のテストと互換性がありません。TestSchedulerは、時間の経過をシミュレートするテストに適しています。

于 2012-08-30T19:16:17.473 に答える
1

問題は、MSTestユニットテストにデフォルトがあることですSynchronizationContext。したがってObserveOnReactiveAsyncCommandWPFコンテキストではなくスレッドプールにマーシャリングします。これにより、競合状態が発生します。

あなたの最初で最良のオプションはRxTestSchedulerです。

もう1つのオプションは、await完了シグナルを送信することです(そして、テストメソッドがasync Taskではないことを確認してくださいasync void)。

それ以外の場合、が必要な場合は、AsyncExライブラリからSynchronizationContext使用して独自の内でテストを実行できます。AsyncContextSynchronizationContext

Dispatcher最後に、の代わりに直接使用するコードがある場合は、非同期CTPダウンロードからSynchronizationContext使用できます。WpfContext

于 2012-08-30T01:31:07.720 に答える