IInvokeProvider.Invoke 在 NUnit 测试中
IInvokeProvider.Invoke in NUnit Test
我有一个 WPF 用户控件,我正在为使用 NUnit 编写一些单元测试。其中一项测试在 window 上显示控件并单击控件上的按钮。之后它会确认收到了正确的结果。
使用 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("");
所以我认为我需要做一些设置才能让事情按照我喜欢的方式运行。也许为调度程序或 Window 设置一个单独的线程。我敢肯定有这样的例子,但我似乎没有在寻找正确的关键词。请注意,NUnit 要求我 运行 使用 RequiresSTA 属性进行单元测试。
我认为你的结论是正确的。 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);
我有一个 WPF 用户控件,我正在为使用 NUnit 编写一些单元测试。其中一项测试在 window 上显示控件并单击控件上的按钮。之后它会确认收到了正确的结果。
使用 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("");
所以我认为我需要做一些设置才能让事情按照我喜欢的方式运行。也许为调度程序或 Window 设置一个单独的线程。我敢肯定有这样的例子,但我似乎没有在寻找正确的关键词。请注意,NUnit 要求我 运行 使用 RequiresSTA 属性进行单元测试。
我认为你的结论是正确的。 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);