TaskPoolScheduler
is not set to Scheduler.Immediate
, so it really is running in the background. Try this:
Scheduler.CurrentThread.With(sched => {
// TODO: Write your code here, now both schedulers are
// rigged to CurrentThread.
});
Question
I use Xamarin and ReactiveUI to do mobile apps.
I'd like to test my ViewModel
and its ReactiveCommand
.
I register an asynchronous operation which return an IObservable inside the ReactiveCommand
.
In ViewModel
constructor :
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;
});
What's in 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);
How to test the ViewModel
login success ? Here is my approach which doesn't work :
[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 :(
}
The test fails because the assertion is made before the command has finished executing.
Resolution
I was subscribing to the Login
command and assumed that my "disconnection block" would be called before the RegisterAsync
's one. Inverted the two would resolve the issue or simply put the "disconnection" logic inside RegisterAsync
like this :
var loginResult = Login.RegisterAsync(_ => {
if (ConnectedUser != null)
{
ConnectedUser.Disconnect();
ConnectedUser = null;
}
Client.Login(Username, Password);
});
Paul Betts ' solution was also necessary.
Solution
TaskPoolScheduler
is not set to Scheduler.Immediate
, so it really is running in the background. Try this:
Scheduler.CurrentThread.With(sched => {
// TODO: Write your code here, now both schedulers are
// rigged to CurrentThread.
});