【发布时间】:2013-02-25 07:56:17
【问题描述】:
我有一个 ReactiveAsyncCommand 暂时只是睡了一会儿:
public ReactiveAsyncCommand SignIn { get; private set; }
//from constructor:
SignIn = new ReactiveAsyncCommand(this.WhenAny(x => x.Username, x => x.Password,
(u, p) =>
!string.IsNullOrWhiteSpace(u.Value) &&
!string.IsNullOrWhiteSpace(p.Value)));
SignIn.RegisterAsyncAction(_ => Thread.Sleep(4000));
我想在命令执行时显示进度指示器,所以我创建了一个属性来绑定它的可见性:
private ObservableAsPropertyHelper<bool> _Waiting;
public bool Waiting
{
get { return _Waiting.Value; }
}
//from constructor:
_Waiting = SignIn.ItemsInflight
.Select(x => x > 0)
.ToProperty(this, x => x.Waiting);
因此,即使它似乎在实践中有效,我也希望有一个单元测试表明,在命令执行时等待始终为真,而且只有在那时。
我已阅读this blogpost about the testscheduler,但很难使用它。
[TestMethod]
public void flag_waiting_while_signing_in()
{
(new TestScheduler()).With(scheduler =>
{
var vm = new SignInViewModel {Username = "username", Password = "password"};
vm.SignIn.Execute(null);
Assert.IsTrue(vm.Waiting);
});
}
此测试失败(等待为假)。我尝试添加对scheduler.start() 和scheduler.advanceBy( ) 的调用,但这没有任何区别。
我的测试方法是否错误? 如果方法是正确的,还有什么是错误的?
编辑
所以我按照建议更改了Thread.Sleep():
SignIn.RegisterAsyncAction(_ =>
{
Observable.Interval(TimeSpan.FromMilliseconds(4000));
});
并尝试通过在检查Waiting 标志之前调用scheduler.AdvanceBy(...) 来控制时间。不过还是没有绿色。
【问题讨论】:
-
您需要改用RegisterAsyncObservable,并指定RxApp.DispatcherScheduler作为Interval的调度器
-
我不确定我是否理解。首先,
RxApp.DispatcherScheduler是指RxApp.DeferredScheduler吗?其次,在 DeferredScheduler 上面的评论中,它说这个调度器用于应该在 ui 线程上运行的工作项。最终,我希望我的登录命令做一些更有用的事情。我在单元测试时使用 deferredscheduler 并在实际工作中使用任务池调度程序的想法是什么?无论如何,测试现在变绿了,但是通过检查标志在 4 秒延迟后重置,它又变红了。还有什么建议吗? -
是的,我的意思是 DeferredScheduler,虽然你是对的,但使用 TaskPoolScheduler 更现实(你会得到相同的结果!)
标签: system.reactive reactiveui