测试ReactiveCommand异步结果

时间:2013-10-25 09:55:26

标签: c# unit-testing reactiveui

我使用Xamarin和ReactiveUI来制作移动应用。

我想测试我的ViewModel及其ReactiveCommand

我注册了一个异步操作,它返回ReactiveCommand内的IObservable。

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之前调用。反过来两个会解决问题或简单地将“断开”逻辑放在RegisterAsync内:

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

Paul Betts'解决方案也是必要的。

1 个答案:

答案 0 :(得分:2)

TaskPoolScheduler未设置为Scheduler.Immediate,因此它确实在后台运行。试试这个:

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