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);
});
ポール・ベッツのソリューションも必要でした。