我试图围绕使用调度程序的自定义控件编写单元测试(例如,针对其依赖项属性)。
在线搜索时,有多个主题相关主题,但没有一个主题提供明确的解决方案。
一种解决方案涉及在DispatcherFrame周围创建DoEvents函数以处理调度程序队列。但是,如果我正在等待单元测试中的某个函数,而调度程序调用位于该函数内部,则永远不会有机会调用DoEvents。
另一种解决方案涉及使用IDispatcher接口创建一个模拟,并仅调用要发送到调度程序的调用。但是,必须从创建它们的同一线程中设置依赖项属性。为此,我需要一个功能强大的调度程序。
最后,最有趣的解决方案是初始化Application对象并使用其分派器。
[AssemblyInitialize]
public static void AssemblyInitialize(TestContext context) {
var waitForApplicationRun = new TaskCompletionSource<bool>();
Task.Run(() => {
var application = new Application();
application.Startup += (s, e) => { waitForApplicationRun.SetResult(true); };
application.Run();
});
waitForApplicationRun.Task.Wait();
}
[AssemblyCleanup]
public static void AssemblyCleanup() {
Application.Current.Dispatcher.Invoke(Application.Current.Shutdown);
}
public Dispatcher Dispatcher = Application.Current.Dispatcher;
现在我得到“调用线程必须是STA,因为许多UI组件都需要STA。”
如何在单元测试中使用它?
作为旁注,可以在不等待的情况下调用Dispatcher.BeginInvoke,还是应该始终等待它?