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



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

因此,尽管它在实践中似乎有效,但我希望有一个单元测试表明,当命令执行时,Waiting allways将是真的,而且只有在那时。

我读过这篇关于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(...)来控制时间。不过还是没有绿色。

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); 
        });
}

最新更新