私はReactiveUIを利用してライブラリについての感想を得るために書きましたWPF-Appを書き直しています。スケジューラ/スロットルをテストするのに推奨される方法
私はこれまでのところ本当に好きです!
今私はThrottle
メソッドを見つけて、コレクションにフィルタを適用するときに使いたいと思っています。
これは私のViewModelです:
namespace ReactiveUIThrottle
{
public class MainViewModel : ReactiveObject
{
private string _filter;
public string Filter { get => _filter; set => this.RaiseAndSetIfChanged(ref _filter, value); }
private readonly ReactiveList<Person> _persons = new ReactiveList<Person>();
private readonly ObservableAsPropertyHelper<IReactiveDerivedList<Person>> _filteredPersons;
public IReactiveDerivedList<Person> Persons => _filteredPersons.Value;
public MainViewModel()
{
Filter = string.Empty;
_persons.AddRange(new[]
{
new Person("Peter"),
new Person("Jane"),
new Person("Jon"),
new Person("Marc"),
new Person("Heinz")
});
var filterPersonsCommand = ReactiveCommand.CreateFromTask<string, IReactiveDerivedList<Person>>(FilterPersons);
this.WhenAnyValue(x => x.Filter)
// to see the problem
.Throttle(TimeSpan.FromMilliseconds(2000), RxApp.MainThreadScheduler)
.InvokeCommand(filterPersonsCommand);
_filteredPersons = filterPersonsCommand.ToProperty(this, vm => vm.Persons, _persons.CreateDerivedCollection(p => p));
}
private async Task<IReactiveDerivedList<Person>> FilterPersons(string filter)
{
await Task.Delay(500); // Lets say this takes some time
return _persons.CreateDerivedCollection(p => p, p => p.Name.Contains(filter));
}
}
}
GUIを使用している場合、フィルタリング自体は、スロットリングも、魔法のように動作します。
しかし、私はフィルタリングの動作をunittestのしたい、これが私の最初の試みである:
[Test]
public void FilterPersonsByName()
{
var sut = new MainViewModel();
sut.Persons.Should().HaveCount(5);
sut.Filter = "J";
sut.Persons.Should().HaveCount(2);
}
コレクションはまだ5人を持っているので、このテストが失敗しました。
await Task.Delay(500)
をFilterPersons
で取り除くと、テストは合格しますが、スロットルから2秒かかります。
1)ユニットテストをスピードアップするために、テスト中にスロットルを瞬時にする方法はありますか?
2)フィルタの非同期動作をテストするにはどうすればよいですか?
私はReactiveUI 7.xのに
ご回答いただきありがとうございます。プロダクションコードとして実行しているときに、モデルに何を注入しますか? 'RxApp.MainThreadScheduler'? –
更新: [テスト] 公共ボイドFilterPersonsByName(){ 新しいTestScheduler()(schedの=> { するvar SUT =新しいMainViewModel(SCHED)で、 がschedの。AdvanceByMs(3000); sut.Persons.Should()。HaveCount(5); sut.Filter = "J"; sched.AdvanceByMs(3000); sut.Persons.Should()。HaveCount(2); }); } が動作します。 2番目のポイントはworkign outです:-)私は 'CurrentThreadScheduler.Instace'を与えても即座に実行されるのではなく、2〜3秒で実行されます –
あなたが好きなのなら、実行時に' RxApp'スケジューラーを使うことができます。個人的には、スケジューラを自分で作成して注入しますが、それは個人的な好みであり、必要ではありません。 –