TestScheduler在订阅的属性上没有像预期的那样工作(w throttle)

时间:2014-12-18 15:13:04

标签: c# system.reactive reactive-programming reactiveui

我对rx / ReactiveUi非常环保并希望使用TestScheduler编写一个xunit测试来检查检索搜索建议的限制是否正常工作。

我们的想法是使用TestScheudler进行计时,更改search-term属性的值并检查是否调用了异步方法。遗憾的是,该方法未在预期位置调用(请参阅附带的代码,尤其是单元测试)。

我错过了什么?我试图测试这个方法是一种好方法吗?

我的观点型号:

public class MyViewModel : ReactiveObject
{
    public MyViewModel (IMyQueryHandler queryHandler)            
    {
        ...
        // Type suggestions
        this.SearchTerms = this.ObservableForProperty(x => x.SearchTerm)
            .Throttle(SuggestionThrottle).Value();

        this.SearchTerms.Subscribe(this.LoadSearchSuggestionsAsync);
        ...
    }

    internal async void LoadSearchSuggestionsAsync(string search)
    { 
        ... 
    this.SearchSuggestions = this.queryHandler.ExecuteQuery(...);
        ...
    }       

    public IList<SearchSuggestion> SearchSuggestions
    {
        get { return this.searchSuggestions; }
        set { this.RaiseAndSetIfChanged(ref this.searchSuggestions, value); }
    }

    ...
} 

我的单元测试(xunit):

...

public class TestFixture : ReactiveObject
{
    public string SearchTerms { get { return this._searchTermsBackingField.Value; } }
    public ObservableAsPropertyHelper<string> _searchTermsBackingField;
}

[Fact]
public void WillTryToLoadSearchSuggestionsAfterThrottleTime()
{
    new TestScheduler().With(
        sched =>
        {                    
            var fixture = new TestFixture();
            var queryClient = Substitute.For<IMyQueryHandler>();

            var caseSuggestions = new List<...> { ... }

            queryClient.ExecuteQuery<...>(...).ReturnsForAnyArgs(...);  // Nsubstitute

            var vm = new MyViewModel(queryClient);

            vm.SearchTerms.ToProperty(fixture, p => p.SearchTerms, out fixture._searchTermsBackingField);

            sched.Schedule(() => vm.SearchTerm = "Tes");
            sched.Schedule(MyViewModel.SuggestionThrottle, () => vm.SearchTerm = "Test");

            sched.AdvanceBy(MyViewModel.SuggestionThrottle.Ticks);
            sched.AdvanceBy(1);

            // why is the method MyViewModel.LoadSearchSuggestionsAsync not called here (in debug)???

            sched.AdvanceBy(1);
         }  // method gets called here...
 }
 ...    

1 个答案:

答案 0 :(得分:4)

Throttle没有设置调度程序,而是编写Throttle(timespan, RxApp.MainThreadScheduler)