MVVMプロジェクトでRxとRxUIを使用していて、WCFサービスからのデータを非同期でクエリするビューモデルがあります。単体テストでは、期待値を持つタスクを返すモックオブジェクトを作成します。
これが私のビューモデルがどのように見えるかの一般的な考え方です
public class ViewModel : ReactiveObject
{
private IContext _context;
public ViewModel(IContext context)
{
_context = context;
Observable.FromAsync(() => _context.WcfServiceCall())
.Subscribe(result => {
Children.AddRange(results.Select(r => new ChildViewModel(r).ToList()));
});
}
public ObservableCollection<ChildViewModel> { get; private set;}
}
私の単体テストは次のようになります
[TestFixture]
public class ViewModelTest : AssertionHelper
{
[Test]
public void ShouldSetChildren()
{
var c = new Mock<IContext>();
c.Setup(q => q.WcfServiceCall())
.Returns(Task.Run(() => new []{ 1,2,3,4,5,6 })):
var vm = new ViewModel(c.Object);
var p = vm.Children.First(); // this call sometimes fails
...
}
}
私が抱えている問題は、この種のことを行う400以上のテストがあり、それらはすべてほとんどの場合機能しますが、シーケンスに値がないことを報告する、一度に1つか2つの失敗したテストをランダムに取得することです。これは予測不可能でランダムです。失敗した後、テストを再度実行して、すべて成功することができます。ここで説明するようにTestSchedulerを追加しましたが、問題は解決しません。
非同期メソッド呼び出しを行うメソッドをテストするためのより良い方法はありますか?
Paul Bettの入力から編集:FromAsyncはISchedulerパラメーターを受け取らないようですが、SubscribeOnとObserveOnを使用できます。
または、WCF非同期メソッドを直接呼び出して、返されたタスクを監視対象に変換することもできます。Observable.FromAsyncを使用する方が適切なのか、使用しない方が適切なのかがわかりません。