[英]Hanging on Application.Current.Dispatcher.Invoke(action) when unit tesing
[英]How to write a WPF async unit test for a method that uses Application.Current.Dispatcher.Invoke?
我们有一个用WPF编写的应用程序。 我正在尝试为在后台线程上运行的某些代码编写单元测试。 在此代码中的某些地方,我们需要在UI线程上执行操作。 在那些地方,我们使用以下代码结构:
Application.Current.Dispatcher.Invoke(new Action(() =>
{
// do something on UI thread
}));
当我创建一个异步单元测试时,它似乎卡在了Invoke方法上。 我猜这是因为调度程序不是“调度”。 我试图通过使用称为DisaptcherUtil的类来解决此问题,该类在互联网上的许多地方都被引用了。 但是我无法使它正常工作。 现在,我的代码的简化版本如下所示:
[TestMethod]
public async Task TestDispatcher()
{
new Application();
DispatcherUtil.DoEvents();
await Task.Run(() => MethodUsingDispatcher());
}
private void MethodUsingDispatcher()
{
Application.Current.Dispatcher.Invoke(new Action(() =>
{
Console.WriteLine("On the dispatchee thread!");
}));
Console.WriteLine("BAck to background trhead");
}
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)
{
Console.WriteLine("ExitFrame");
((DispatcherFrame)frame).Continue = false;
return null;
}
}
当我运行名为“ TestDispatcher”的测试时,它会挂起。
任何人都知道为什么会这样吗? 这是执行此操作的正确方法,还是应该改走为我可以在测试中模拟的Dispatcher创建接口的路线。 我已经在某些地方看到了这一点。
我要说的是,您应该将分派隐藏在接口后面,并在单元测试中模拟它:
interface IDispatcher
{
void Dispatch(Action action);
}
您可以在测试中轻松模拟这一点,并期待那些已调度的调用。
使用真正的调度程序的实现,可以由您的应用程序使用:
public class Dispatcher
{
public void Dispatch(Action action)
{
Application.Current.Dispatcher.Invoke(action);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.