Reactiveui ObservablesPropertyHelper-必须访问值才能订阅?

Reactiveui ObservablesPropertyHelper-必须访问值才能订阅?,reactiveui,Reactiveui,我最近将我的ReactiveUI nugget软件包更新为最新的预发布版本(v5.99.4-beta)。我已经有一段时间没有更新了,但是我在ViewModel上的许多测试都失败了 调试器似乎表明我的正常接收序列没有被订阅。例如: _executeSearch = ReactiveCommand.Create(); var paper = _executeSearch .Where(x => x is string) .Sele

我最近将我的ReactiveUI nugget软件包更新为最新的预发布版本(v5.99.4-beta)。我已经有一段时间没有更新了,但是我在ViewModel上的许多测试都失败了

调试器似乎表明我的正常接收序列没有被订阅。例如:

  _executeSearch = ReactiveCommand.Create();
  var paper = _executeSearch
              .Where(x => x is string)
              .SelectMany(x => _searchParser.GetPaperFinders(x as string))
              .SelectMany(x => x.FindPaper());
  paper
       .Select(x => x.Item1.Title)
       .ToProperty(this, x => x.Title, out _TitleOAPH, "");
我的测试代码看起来像这样(为了简洁起见):

我查看了github上的reactiveui源代码,发现ObservablesPropertyHelper对象上的“value”属性有以下内容:

    public T Value {
        get { 
            _inner = _inner ?? _source.Connect();
            return _lastValue; 
        }
    }
这里的关键行是“\u source.Connect()”——简言之,只有在有人访问该值时才订阅该序列。在我的测试中,如果我在运行任何rx序列之前放置一个“vm.Title”,那么一切都正常

这是一个令人惊讶的行为(至少对我来说),因为必须先访问ObservablePropertyHelper.Value属性,然后才能捕获任何值。这是预期的行为吗?是否出于效率(例如延迟实例化)原因而进行了此操作?如果是这样的话,在测试中解决这个问题的正确方法是什么

还是我对这一过程的理解非常错误?:-)

这是预期的行为吗

是的,这是ReactiveUI 6.0的新功能

是否出于效率(例如延迟实例化)原因而进行了此操作

正确-它实际上可以节省大量内存和工作!(我记得早期测试时在GitHub for Windows中有15-20%的内存)

不过这是一个有趣的场景——我怀疑在单元测试运行程序中,我们应该订阅构造,类似于RXUI5.x

编辑:我会这样写:

_executeSearch = ReactiveCommand.Create(_ => Observable.Return(x)
    .Where(x => x is string)
    .SelectMany(x => _searchParser.GetPaperFinders(x as string))
    .SelectMany(x => x.FindPaper()));

_executeSearch
   .Select(x => x.Item1.Title)
   .ToProperty(this, x => x.Title, out _TitleOAPH, "");
现在,您可以更轻松地编写测试方法,而无需TestScheduler:

var vm = new AddCDSPaperViewModel(obj, parser);
var result = await vm.ExecuteSearch.ExecuteAsync("Some String");
Assert.AreEqual("title", result.Title);

如何让单元测试运行程序订阅构造?我甚至不知道我是如何知道所有具有ObservablesPropertyHelper的属性的。或者您的意思是创建一个全局标志,然后在设置时让ObservablesProertyHelper订阅?如果它使单元测试的行为与真实世界不同,则必须小心。。。也许我的单元测试结构不正确?很好,谢谢。我会调查的。然而,实际上,我需要测试其中的等待、超时和反弹跳逻辑,所以我仍然需要测试调度器-我刚刚放弃了上面问题中的所有内容。不过,我还是更喜欢你们的组织。啊,在这种情况下,使用TestScheduler,但是ExecuteAsync仍然更容易。当然,我只是尝试了一下。我喜欢在其中加入更多的逻辑,阻止我的是我认为订阅_executeSearch会返回传递给ReactiveCommand上的“Execute”方法的参数,而不是异步调用的结果。我一定是糊涂了!不用担心,新的命令是全新的,除了公关,还没有关于它的文档
var vm = new AddCDSPaperViewModel(obj, parser);
var result = await vm.ExecuteSearch.ExecuteAsync("Some String");
Assert.AreEqual("title", result.Title);