我有一个方法,我试图从单元测试中调用。
这种方法在现实生活中将从后台线程运行。它使用一些代码启动对UI线程的调用更新(使用Application.Current.Dispatcher.BeginInvoke
....)。
但是,从单元测试中调用时,Application.Current
为null
。
我真的不想把if (Application.Current !=null)
放在需要解决的所有事情上。
还有其他方法吗?
_statusUpdates是一个ObservableCollection
下面是我要测试的方法中的代码部分(它更像是集成测试,而不是单元测试才公平)。
Application.Current.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, (EventHandler)delegate
{
_statusUpdates.Add(new StatusUpdate
{
DateTime = DateTime.Now,
Message = "Checking For Messages"
});
}, null, null);
答案 0 :(得分:14)
以下代码段适用于我:
if (System.Windows.Application.Current == null)
{ new System.Windows.Application { ShutdownMode = ShutdownMode.OnExplicitShutdown }; }
IIRC,我遇到一个问题,其中Application使用嵌入在WinForms应用程序中的WPF控件为null,并且在StackOverflow的另一个问题中建议将该代码片段作为问题的解决方案(抱歉,无法找到源代码)。它在单元测试中解决了同样的问题(我不认为在这种情况下需要显式设置ShutdownMode属性。)
答案 1 :(得分:11)
如前所述,您在单元测试期间根本不会有Application
课程。
那就是说,我认为需要解决这个问题 - 通过让代码依赖于定义的静态属性,在你的情况Application.Current.Dispatch
中,你现在非常紧密耦合到该类的具体实现,即WPF Application
类,您不需要这样做。
即使您只是将“当前根调度程序”的概念包含在Singleton
样式的类包装器中,现在您还可以将自己与Application
类的变幻莫测和处理分开。直接与您关心的是Dispatcher
:
注意,有很多方法可以写这个,我只是提出了最简单的实现方法;因此,我不会进行任何多线程安全检查等。
public class RootDispatcherFetcher
{
private static Dispatcher _rootDispatcher = null;
public static Dispatcher RootDispatcher
{
get
{
_rootDispatcher = _rootDispatcher ??
Application.Current != null
? Application.Current.Dispatcher
: new Dispatcher(...);
return _rootDispatcher;
}
// unit tests can get access to this via InternalsVisibleTo
internal set
{
_rootDispatcher = value;
}
}
}
好的,现在这个实现只比之前的略微更好,但至少你现在可以更好地控制对类型的访问,并且不再严格依赖于{{1}的存在实例。
答案 2 :(得分:2)
使用_editUser()
代替Dispatcher.CurrentDispatcher
获取当前线程的System.Windows.Threading.Dispatcher 执行并创建一个新的System.Windows.Threading.Dispatcher(如果有) 尚未与该主题相关联。
答案 3 :(得分:0)
单元测试运行器中没有Application对象。这些通常是基于“控制台”的应用程序,它们只运行和执行非UI代码(“单元”)。
我建议您不要使用单元测试框架来测试特定于UI的信息,我建议使用自动UI测试框架来实现这一点。
答案 4 :(得分:-1)
所以这里的问题是必须在某处创建Application对象。因此,您需要找到实例化System.Windows.Application
(或某个后代)类的位置。
如果项目是从模板构建的,那么您可能会在App.xaml文件中找到此类。你只需要确保以某种方式实例化它。否则,在整个项目中搜索Application
类,然后您必须手动实例化它。应该解决它。