Application.Current имеет значение null при вызове с unittest - программирование
Подтвердить что ты не робот

Application.Current имеет значение null при вызове с unittest

У меня есть метод, который я пытаюсь вызвать из unit test. Этот метод в реальной жизни будет запущен из фонового потока. Он использует некоторый код для запуска в вызове обновлений потока пользовательского интерфейса (используя Application.Current.Dispatcher.BeginInvoke....).

Однако Application.Current является null при вызове из модульных тестов.

На самом деле, я действительно не помещаю if (Application.Current !=null) вокруг всего, чтобы исправить.

Есть ли другой способ?

_statusUpdates - это ObservableCollection

Ниже приведена часть кода в методе, который я пытаюсь проверить (это скорее интеграционный тест, чем unit test).

Application.Current.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, (EventHandler)delegate
{
    _statusUpdates.Add(new StatusUpdate
    {
        DateTime = DateTime.Now,
        Message = "Checking For Messages"
    });
}, null, null);
4b9b3361

Ответ 1

Как уже было сказано, вы просто не будете иметь класс Application во время модульных тестов.

Тем не менее, здесь проблема, о которой я думаю, требует адресации - имея код, который полагается на определенное статическое свойство, в вашем случае Application.Current.Dispatch, вы теперь очень тесно связаны с конкретной реализацией этого класса, а именно класс WPF Application, где вам не нужно быть.

Даже если вы просто оберните идею "текущего диспетчера корней" в оболочке класса Singleton -style, теперь у вас есть способ отделить себя от капризов класса 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;
         }
     }
}

Итак, теперь эта реализация немного лучше, чем раньше, но по крайней мере у вас теперь есть более тонкий контроль над доступом к типу и больше не зависит от существования экземпляра Application.

Ответ 2

Следующий фрагмент кода работает для меня:

if (System.Windows.Application.Current == null) 
  { new System.Windows.Application { ShutdownMode = ShutdownMode.OnExplicitShutdown }; }

IIRC, у меня была проблема, когда Application было null, используя элемент управления WPF, встроенный в приложение WinForms, и этот фрагмент кода был предложен как решение проблемы в другом вопросе в StackOverflow (извините, не могу найти источник). Он решает ту же проблему в модульных тестах (и я не считаю, что свойство ShutdownMode должно быть явно задано в этом случае).

Ответ 3

У вас не будет объекта Application в run-run unit. Обычно это "консольные" приложения, которые просто запускают и выполняют код, отличный от UI ( "единицы" ).

Я предлагаю вам не использовать фреймворк unit test для проверки информации, специфичной для пользовательского интерфейса, для этого я предлагаю схему автоматического тестирования пользовательского интерфейса.

Ответ 4

Итак, проблема здесь в том, что где-то должен быть создан ваш объект приложения. Поэтому вам нужно найти, где создается экземпляр класса System.Windows.Application (или нескольких потомков).

Если проект был создан из шаблона, вы, вероятно, найдете этот класс в файле App.xaml. Вам просто нужно убедиться, что это каким-то образом создается. Else, выполните поиск всего проекта для класса Application, а затем вам придется создавать его вручную. Должен исправить это.