0

Xamarin と ReactiveUI を使用してモバイル アプリを実行しています。

ViewModelとそのをテストしたいと思いReactiveCommandます。

内で IObservable を返す非同期操作を登録しますReactiveCommand

ViewModelコンストラクターで:

Login = new ReactiveCommand();
var loginResult = Login.RegisterAsync(_ => Client.Login(Username, Password));
loginResult.ObserveOn(RxApp.MainThreadScheduler).BindTo(this, self => self.ConnectedUser);
Login
    .Where(_ => ConnectedUser != null)
    .Subscribe(_ => {
        ConnectedUser.Disconnect();
        ConnectedUser = null;
    });

Client.Login内容:

return Observable.Start(async () => {
    // Do an HTTP POST to login the user, with await stuff in
    // Return the User on success or throw an exception on error
}, RxApp.TaskpoolScheduler)
.Select(task => task.Result);

ViewModelログインの成功をテストする方法は? うまくいかない私のアプローチは次のとおりです。

[Test]
public void TestLoginSuccess()
{
    ViewModel viewModel = new ViewModel();
    viewModel.Username = "toto";
    viewModel.Password = "****";

    viewModel.Login.Execute(null);

    Assert.That(viewModel.ConnectedUser, Is.Not.Null); // always null so fail :(
}

コマンドの実行が完了する前にアサーションが行われるため、テストは失敗します。

解像度

Login私はコマンドをサブスクライブしていて、「切断ブロック」が「切断ブロック」RegisterAsyncの前に呼び出されると想定していました。2つを逆にすると、問題が解決するか、単に「切断」ロジックを次のRegisterAsyncように内部に配置できます。

var loginResult = Login.RegisterAsync(_ => {
    if (ConnectedUser != null)
    {
        ConnectedUser.Disconnect();
        ConnectedUser = null;
    }
    Client.Login(Username, Password);
});

ポール・ベッツのソリューションも必要でした。

4

1 に答える 1

2

TaskPoolSchedulerに設定されていないScheduler.Immediateため、実際にはバックグラウンドで実行されています。これを試して:

Scheduler.CurrentThread.With(sched => {
    // TODO: Write your code here, now both schedulers are
    // rigged to CurrentThread.
});
于 2013-10-26T01:24:32.853 に答える