c# - 在单元测试中使用 WPF Dispatcher 的正确方法

标签 c# wpf unit-testing nunit dispatcher

我正在尝试遵循 Using the WPF Dispatcher in unit tests 中的建议为了运行我的 nUnit 测试。

当我如下编写单元测试时,它有效:

[Test]
public void Data_Should_Contain_Items()
{
    DispatcherFrame frame = new DispatcherFrame();
        PropertyChangedEventHandler waitForModelHandler = delegate(object sender, PropertyChangedEventArgs e)
        {
          if (e.PropertyName == "Data")
          {
            frame.Continue = false;
          }
        };
    _myViewModel.PropertyChanged += waitForModelHandler;
    Dispatcher.PushFrame(frame);

    Assert.IsTrue(_myViewModel.Data.Count > 0, "Data item counts do not match");
}

但是,如果我尝试使用 DispatcherUtil 的建议,它不起作用:

[Test]
public void Data_Should_Contain_Items()
{
    DispatcherUtil.DoEvents();
    Assert.IsTrue(_myViewModel.Data.Count > 0, "Data item counts do not match");
}

public static class DispatcherUtil
{
    [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
    public static void DoEvents()
    {
        DispatcherFrame frame = new DispatcherFrame();
        Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
            new DispatcherOperationCallback(ExitFrame), frame);
        Dispatcher.PushFrame(frame);
    }

    private static object ExitFrame(object frame)
    {
        ((DispatcherFrame)frame).Continue = false;
        return null;
    }
}

当我使用 DispatcherUtil 时,似乎在数据准备好之前调用 ExitFrame 的时间过早。

我没有正确使用 DispatcherUtil 吗?这似乎是一种更好的方法来处理调度程序,而不是等待来自 View 模型的回调。

最佳答案

由于调度程序在单元测试中存在问题,我的解决方案是打破 View 模型对调度程序的依赖。我假设目前您有硬编码的引用,例如:

Dispatcher.CurrentDispatcher.BeginInvoke(..

调度程序是一个外部依赖项,不应成为单元测试的一部分 - 我们可以假设调度程序正常工作。

我会使用依赖注入(inject)(穷人、Unity 等)。 创建一个代表调度程序的合适接口(interface)。 创建一个包装真实调度程序的真实实现。 创建一个使用 Action.BeginInvoke 的假实现。 在假的中,您记录了所有返回给 BeginInvoke 调用的 IAsyncResults。
然后有一个辅助方法,它会等待所有调用完成,您可以在测试中使用它来等待完成。

或者有一个 View 模型基类做同样的事情。正常调用调度程序,但可以在测试期间被指示调用假的。

关于c# - 在单元测试中使用 WPF Dispatcher 的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9336165/

相关文章:

c# - 属性或索引器不能分配给 “--” 它是只读的 C# List<Tuple<string, bool>>

c# - WPF 样式未在运行时应用

unit-testing - 为什么即使使用 Spocks 的 Mock() 模拟了底层 Controller ,此方法仍返回 null?

javascript - Jest 测试总是在导入 './environment/validate' 时失败;

c# - Microsoft Service Fabric 有状态服务无法启动

c# - Web 服务拒绝接收参数并以 JSON 格式回复

c# - 如何计算从今天算起的8个工作日?

wpf - DependencyProperty 值未通过数据绑定(bind)设置

wpf - 使用Entity Framework 4创建Blob属性吗?

oracle - 如何(单元)测试数据密集型PL/SQL应用程序