使用ObserveOnDispatcher </t>对IObservable <t>进行单元测试

时间:2012-07-04 15:16:14

标签: c# linq reactiveui

我需要测试一段代码

        var watcher = new FakeIFileSystemWatcher();
        watcher.FilesToBeImported
            .ObserveOnDispatcher()
            .Subscribe(list.Add);

所以我创建了这个小单元测试,但我无法使它通过原因list.Count始终为0

    [Test]
    public void Foo()
    {
        var list = new List<string>();

        var watcher = new FakeIFileSystemWatcher();
        watcher.FilesToBeImported
            .ObserveOnDispatcher()
            .Subscribe(list.Add);

        Task task = Task.Factory.StartNew(() =>
        {                
            watcher.AddFile("cc");
            watcher.AddFile("cc");
            watcher.AddFile("cc");
        }, TaskCreationOptions.LongRunning);
        Task.WaitAll(task);

        Assert.AreEqual(3, list.Count);
    }

如果我注释掉方法

            .ObserveOnDispatcher()

它通过但我如何才能使用ObserveOnDispatcher()?

3 个答案:

答案 0 :(得分:6)

如果使用ObserveOnDispatcher,则会为“调度程序”创建依赖项,这意味着您需要一个窗口和一个消息循环。要在单元测试中解决此问题,您可以改为使用使用调度程序的ObserveOn方法,然后使用依赖项注入来注入正确的调度程序。对于单元测试,您可以使用Scheduler.Immediate,对于实际应用,您可以使用DispatcherScheduler.Instance。请注意,还存在TestScheduler,它对于在虚拟时间运行单元测试非常有用。

答案 1 :(得分:1)

我使用我在这里找到的类DispatcherUtil解决了 Using the WPF Dispatcher in unit tests

现在我的代码是以下

    [Test]
    public void Foo()
    {
        var list = new List<string>();

        var watcher = new FakeIFileSystemWatcher();
        watcher.FilesToBeImported
            .ObserveOnDispatcher()
            .Subscribe(list.Add);

        Task task = Task.Factory.StartNew(() =>
        {
            watcher.AddFile("cc");
            watcher.AddFile("cc");
            watcher.AddFile("cc");
            watcher.AddFile("cc");
        }, TaskCreationOptions.LongRunning);
        Task.WaitAll(task);
        DispatcherUtil.DoEvents();
        Assert.AreEqual(4, list.Count);
    }

它就像一个魅力

答案 2 :(得分:0)

您可以尝试像这样调用您的方法:

var dispatcher = Application.Current != null ? Application.Current.Dispatcher : Dispatcher.CurrentDispatcher;

 dispatcher.Invoke((Action)(() => YourMethodToTest());