Тестирование элемента управления WPF без добавления его в окно - PullRequest
11 голосов
/ 20 августа 2011

У меня есть UserControl, который публикует сообщение EventAggregator в своем событии Loaded.Чтобы проверить это (и получить событие Loaded), я в настоящее время создаю окно и добавляю к нему элемент управления, затем жду, пока будет вызвано событие Loaded.

Есть ли способнастроить тест так, чтобы событие Loaded срабатывало без необходимости создавать и добавлять элемент управления в окно?

Например:

[Test, RequiresSTA]
public void active_thingy_message_is_published_on_loaded()
{
    const string TestMsg = "Active thingy changed";

    using (AutoResetEvent loadedEvent = new AutoResetEvent(false))
    {
        DummyEventService eventService = new DummyEventService();                
        DummyControl control = new DummyControl(eventService, TestMsg);
        control.Loaded += delegate { loadedEvent.Set(); };

        Assert.That(eventService.Message, Is.Null, "Before.");
        Window window = new Window { Content = control };
        window.Show();                
        loadedEvent.WaitOne();
        window.Dispatcher.InvokeShutdown();
        Assert.That(eventService.Message, Is.EqualTo(TestMsg), "After.");
    }
}

private class DummyControl : UserControl
{
    public DummyControl(DummyEventService eventService, string testMsg)
    {
        Loaded += delegate { eventService.Publish(testMsg); };
    }
}

private class DummyEventService
{
    public string Message { get; private set; }
    public void Publish(string msg) { Message = msg; }
}

Обновление

Я изменил название с «Unit Testing ...» на «Testing ...» и заменил тег «unit-testing» на «testing».

Я бы предпочелне разбивать волосы на том, что это за класс, так как это не конструктивно.Да, можно утверждать, что это не «Модульный тест», но это не полезно.Я хочу протестировать проблему, которая зависит от жизненного цикла элемента управления, и это включает событие Loaded.Это важный регрессионный тест, поскольку сторонние компоненты, над которыми я не могу контролировать, зависят от сообщения, выдаваемого при Loaded.

Может ли событие Loaded быть вызвано без добавления элемента управления в окно?

Ответы [ 3 ]

7 голосов
/ 29 августа 2011

Если вы просто заинтересованы в том, чтобы запустить событие Loaded целевого элемента управления, тогда Reflection должна сделать свое дело.

public static void RaiseLoadedEvent(FrameworkElement element)
{
    MethodInfo eventMethod = typeof(FrameworkElement).GetMethod("OnLoaded",
        BindingFlags.Instance | BindingFlags.NonPublic);

    RoutedEventArgs args = new RoutedEventArgs(FrameworkElement.LoadedEvent);

    eventMethod.Invoke(element, new object[] { args });
}

Это буквально вызывает метод OnLoaded, присутствующий в каждом FrameworkElement, поэтому, если для вашего теста требуется состояние приложения, это не сработает.

Кроме того, нет никакого отношения между событием Loaded родителя и его потомков. Если тест требует, чтобы дочерние элементы запускали свои события Loaded, вспомогательный метод должен будет вручную обходить дочерние элементы управления и запускать их.

7 голосов
/ 12 сентября 2013

За последние два года, возможно, все изменилось. Ради покрытия кода я столкнулся и с этой проблемой, и ее решение.

WPF UIElements наследуют метод с именем RaiseEvent, который принимает RoutedEventArgs. Это может быть создано с использованием конкретного UIElement .LoadedEvent, что позволяет вам получить этот последний бит покрытия кода.

Я сомневаюсь, что вам все еще нужен мой ответ, но кто-то может.

5 голосов
/ 22 августа 2011

Измените то, что в обработчике событий Loaded, на собственный метод, и обработчик событий Loaded вызовет его.Напишите свой юнит-тест для проверки рефакторированного метода, а не события Loaded.

Юнит-тестирование проверяет, что юнит выполняет то, что должен делать.Тестирование взаимодействия устройства с другими устройствами является интеграционным тестированием.Конечно, полезно проводить интеграционное тестирование и иметь возможность регрессионного тестирования интегрированных модулей, но это задача, отличная от модульного тестирования.

Наконец: если вы не уверены, что событие элемента управления Loadedзапуск при загрузке (что является основной причиной того, что вы будете проводить интеграционные тесты, подобные этой), что-то не так, и вы должны исследовать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...