从unittest调用时,Application.Current为null

时间:2013-02-12 17:00:44

标签: c# wpf unit-testing

我有一个方法,我试图从单元测试中调用。 这种方法在现实生活中将从后台线程运行。它使用一些代码启动对UI线程的调用更新(使用Application.Current.Dispatcher.BeginInvoke ....)。

但是,从单元测试中调用时,Application.Currentnull

我真的不想把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);

5 个答案:

答案 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类,然后您必须手动实例化它。应该解决它。