ReactiveUI:在ReactiveAsyncCommand执行时测试进度指示器可见性

时间:2013-02-23 23:55:16

标签: system.reactive reactiveui

我有一个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));
            });

在检查scheduler.AdvanceBy(...) - 标志之前,尝试通过调用Waiting来控制时间。尽管如此,仍然没有绿色。

1 个答案:

答案 0 :(得分:1)

TestScheduler倒闭的原因是,你有一个异步的来源,不在TestScheduler的视图之外 - Thread.Sleep。它无法控制它,总是占用4秒。将其替换为Observable.Interval代替它,它应该按预期工作

[TestMethod]
public void flag_waiting_while_signing_in()
{

    (new TestScheduler()).With(scheduler =>
        {
            var vm = new SignInViewModel {Username = "username", Password = "password"};

            vm.SignIn.Execute(null);

            scheduler.AdvanceBy(TimeSpan.FromMilliseconds(2000));
            Assert.IsTrue(vm.Waiting); 

            // Move past the end
            scheduler.AdvanceBy(TimeSpan.FromMilliseconds(5000));
            Assert.IsFalse(vm.Waiting); 
        });
}