【问题标题】:IInvokeProvider.Invoke in NUnit TestNUnit 测试中的 IInvokeProvider.Invoke
【发布时间】:2015-04-22 19:14:48
【问题描述】:

我有一个 WPF 用户控件,我正在编写一些使用 NUnit 的单元测试。其中一项测试在窗口上显示控件并单击控件上的按钮。之后,它会确认收到了正确的结果。

使用 RaisedEvents 它看起来像这样并且可以正常工作。

MyButton.RaiseEvent(buttonArgs);
Assert.AreEqual(expected, actual);

我正在尝试使用自动化框架来做同样的事情。比如:

ButtonAutomationPeer peer = new ButtonAutomationPeer(MyButton);
IInvokeProvider invokeProv = (IInvokeProvider)(peer.GetPattern(PatternInterface.Invoke));
invokeProv.Invoke();
Assert.AreEqual(expected, actual);

现在在这种情况下,断言失败(如预期的那样),因为 Invoke 是异步调用的,并且在断言时尚未发生。

我希望通过在单独的线程上调用 Invoke 并等待它完成来解决此问题。

Thread thread = new Thread(invokeProv.Invoke);
thread.Start();
thread.Join();

但是这仍然失败。和睡觉一样:

invokeProv.Invoke();
Thread.Sleep(1000);

显示一个对话框并强制用户继续,但确实有效。

invokeProv.Invoke();
System.Windows.MessageBox.Show("");

所以我认为我需要做一些设置才能让事情以我喜欢的方式运行。也许为调度程序或窗口设置一个单独的线程。我敢肯定那里有这样的例子,但我似乎没有在正确的关键词上搜索。请注意,NUnit 要求我使用 RequiresSTA 属性运行单元测试。

【问题讨论】:

  • @mikez 做到了。谢谢。
  • 好的,我会发布作为答案。

标签: c# wpf nunit ui-automation


【解决方案1】:

我认为你的结论是正确的。 IInvokeProvider.Invoke 是异步的,就像 Dispatcher.BeginInvoke 是异步的一样。它只是将消息放入队列以供调度程序处理。但是,在显示消息框之前,您不会启动线程的调度程序。您可能想要 this 之类的东西来处理测试线程中的调度程序操作。

public static void DoEvents()
{
    DispatcherFrame frame = new DispatcherFrame();
    Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
            new DispatcherOperationCallback(ExitFrame), frame);
    Dispatcher.PushFrame(frame);
}

public static object ExitFrame(object f)
{
    ((DispatcherFrame)f).Continue = false;
    return null;
}

可以这样使用:

ButtonAutomationPeer peer = new ButtonAutomationPeer(MyButton);
IInvokeProvider invokeProv = (IInvokeProvider)(peer.GetPattern(PatternInterface.Invoke));
invokeProv.Invoke();
DoEvents();
Assert.AreEqual(expected, actual);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-03
    • 2012-04-01
    相关资源
    最近更新 更多