本文介绍了ReactiveUI:在 ReactiveAsyncCommand 执行时测试进度指示器的可见性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 ReactiveAsyncCommand ,它现在只是睡了一会儿:

I have a ReactiveAsyncCommand that for the moment are just sleeping for a while:

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

我想在命令执行时显示进度指示器,因此我创建了一个属性来绑定其可见性:

I want to show a progress indicator while the command executes, so I have made a property to bind its visibility against:

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

因此,即使它在实践中似乎可行,我还是希望有一个单元测试,表明在命令执行时等待总是为真,并且只有在那时.

So, even though it seems to work in practice, I would love a unit test showing that Waiting allways will be true while the command executes, and only then.

我已阅读 这篇关于测试调度程序的博文,但很难将其投入使用.

I have read this blogpost about the testscheduler, but struggle to put it to use.

    [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( ) 的调用,但这没有任何区别.

This test fails (waiting is false). I have tried to add a calls to scheduler.start() and scheduler.advanceBy( ) but that didn't make any difference.

我的测试方法是错误的吗?如果方法是对的,还有什么问题?

Is my approach to testing this wrong?If the approach is right, what else is wrong?

编辑
所以我按照建议更改了 Thread.Sleep() :

SignIn.RegisterAsyncAction(_ =>
            {
                Observable.Interval(TimeSpan.FromMilliseconds(4000));
            });

并尝试通过在检查 Waiting 标志之前调用 scheduler.AdvanceBy(...) 来控制时间.不过还是没有绿色.

And tried to control time by calling scheduler.AdvanceBy(...) before checking the Waiting-flag. Still no green, though.

推荐答案

TestScheduler 失败的原因是,您有一个不在 TestScheduler 视图中的异步源 - Thread.Sleep.它无法控制它,它总是需要 4 秒.用 Observable.Interval 代替它,它应该可以按预期工作

The reason that TestScheduler is falling over, is that you have a source of asynchrony that is outside TestScheduler's view - the Thread.Sleep. There's no way that it can control it, it will always take up 4 real seconds. Replace it with an Observable.Interval instead and it should work as you expect

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

这篇关于ReactiveUI:在 ReactiveAsyncCommand 执行时测试进度指示器的可见性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-01 05:51