[英]Testing ReactiveCommand async result
I use Xamarin and ReactiveUI to do mobile apps. 我使用Xamarin和ReactiveUI来做移动应用程序。
I'd like to test my ViewModel
and its ReactiveCommand
. 我想测试我的
ViewModel
及其ReactiveCommand
。
I register an asynchronous operation which return an IObservable inside the ReactiveCommand
. 我注册了一个异步操作,它返回
ReactiveCommand
的IObservable。
In ViewModel
constructor : 在
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;
});
What's in Client.Login
: 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 ? 如何测试
ViewModel
登录成功? 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. 我订阅了
Login
命令并假设我的“断开块”将在RegisterAsync
之前被调用。 Inverted the two would resolve the issue or simply put the "disconnection" logic inside RegisterAsync
like this : 反过来两个会解决问题或简单地将“断开”逻辑放在
RegisterAsync
如下所示:
var loginResult = Login.RegisterAsync(_ => {
if (ConnectedUser != null)
{
ConnectedUser.Disconnect();
ConnectedUser = null;
}
Client.Login(Username, Password);
});
Paul Betts ' solution was also necessary. Paul Betts的解决方案也是必要的。
TaskPoolScheduler
is not set to Scheduler.Immediate
, so it really is running in the background. TaskPoolScheduler
未设置为Scheduler.Immediate
,因此它确实在后台运行。 Try this: 尝试这个:
Scheduler.CurrentThread.With(sched => {
// TODO: Write your code here, now both schedulers are
// rigged to CurrentThread.
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.