2013-10-25 2 views
0

Я использую Xamarin и ReactiveUI для мобильных приложений.Тестирование ReactiveCommand async result

Я бы хотел проверить мои 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 «s. Перевернули два бы решить эту проблему или просто поставить «разъединение» логику внутри RegisterAsync так:

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

Paul Betts решение »было также необходимо.

+0

Можете ли вы также добавить журнал из окна вывода. Обычно я ожидаю, что ReactiveUI сообщит вам, что он настроил свое планирование немедленно, пока тестирование было обнаружено. – AlSki

ответ

1

TaskPoolScheduler не установлен в Scheduler.Immediate, поэтому он действительно работает в фоновом режиме. Попробуйте следующее:

Scheduler.CurrentThread.With(sched => { 
    // TODO: Write your code here, now both schedulers are 
    // rigged to CurrentThread. 
}); 
+0

Кажется, правильно упорядочить работу (я проверил, используя некоторые точки останова, и они запускаются в правильном порядке), но привязка к ConnectedUser не выполняется до утверждения. ConnectedUser остается пустым после выполнения команды Login. – nverinaud

Смежные вопросы