Тестирование окна WPF со статическими ресурсами

У меня есть простое окно со ссылкой на StaticResource в App.xaml.

Определение ресурса App.xaml:

<!-- Standard Text Box Style -->
<Style x:Key="textBoxStyleStd" TargetType="{x:Type TextBox}">
    <Setter Property="FontSize" Value="14" />
</Style>

Компоненты окна с использованием ресурса:

<TextBlock Grid.Column="1" Grid.Row="0" Name="stationIdTitle"
           Style="{StaticResource textBlockStyleStd}"
           VerticalAlignment="Center" HorizontalAlignment="Center"
           Text="{LocText Key=Title, Dict={StaticResource Dictionary},
               Assembly={StaticResource Assembly}}"/>

При попытке unit test в этом окне я получаю сообщение об ошибке:

System.Windows.Markup.XamlParseException: не удается найти ресурс с именем '{TextBlockStyleStd}'. Имена ресурсов чувствительны к регистру. Ошибка при object 'stationIdTitle' в файле разметки 'Zpg; компонент /guicomponenets/screens/enterstationidscreen.xaml' Line 23 Позиция 71.

Есть ли способ обойти это? Мой unit test код:

[Test]
public void TestEnterKeyPressedNoText()
{
    IPickingBusinessObject pickingBusinessObject = mock.StrictMock<IPickingBusinessObject>();

    EnterStationIdScreen objectUnderTest = new EnterStationIdScreen(pickingBusinessObject);

    Assert.AreEqual(Visibility.Visible, objectUnderTest.stationIdError.Visibility);

    Assert.AreEqual("werwe", "oksdf");

    Replay();

    objectUnderTest.EnterKeyPressed();

    Verify();
}

Ответ 1

Спасибо Кент,

Я рассмотрел ваши предложения, и в большинстве сценариев я согласен, что модели должны использоваться и проверяться, однако есть некоторый код, связанный с элементами управления (например, видимость TextBox). Я все еще хотел протестировать. Чтобы обойти это, вы можете создать экземпляр своего приложения (но не инициализировать его) и добавить ресурсы вручную. Это приводит к дублированию в App.xaml и базе unit test, но это позволяет мне завершить те тесты, которые я хотел.

        if (Application.Current == null)
        {
            App application = new App();

            #region Add Static Resources from the App.xaml

            Style textBoxStyle = new Style(typeof(TextBox));
            textBoxStyle.Setters.Add(new Setter(TextBox.FontSizeProperty, 14d));

            Style textBlockStyle = new Style(typeof(TextBlock));
            textBlockStyle.Setters.Add(new Setter(TextBlock.FontSizeProperty, 14d));

            application.Resources.Add("TextBoxStyleStd", textBoxStyle);
            application.Resources.Add("TextBlockStyleStd", textBlockStyle);
            application.Resources.Add("TextBlockStyleError", textBlockStyle);
            application.Resources.Add("Assembly", "Zpg");

            #endregion
        }       

Ответ 2

В контексте вашего unit test нет приложения WPF. Поэтому Window не найдет ресурс.

Мой путь вокруг этого будет состоять не в том, чтобы unit test ваши взгляды. Вместо этого используйте MVVM и unit test ваши модели просмотра. Если вы хотите протестировать свои взгляды, вместо этого напишите тесты интеграции. Ваши интеграционные тесты могут фактически запускать приложение и, следовательно, гораздо более точно имитировать реальную работу вашего приложения.

Ответ 3

Когда я использую полностью квалифицированные имена сборки в моих ресурсах ресурсов app.xaml, мне нужно всего лишь инициировать класс App(). В этом примере все ресурсы находятся в сборке Majesty_of_Omega_GUI, которая передается UnitTest.DLL

<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Majesty_of_Omega.GUI.App"
StartupUri="Pages/MainPage.xaml"
>
<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/Majesty_of_Omega_GUI;component/Resources/MainScreens.xaml" />
            <ResourceDictionary Source="pack://application:,,,/Majesty_of_Omega_GUI;component/Resources/PanelResources.xaml" />
            <ResourceDictionary Source="pack://application:,,,/Majesty_of_Omega_GUI;component/Simple Styles.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>
</Application>

Функция тестирования:

    [Test]
    public void Testfunction()
    {
        if (Application.Current == null)
        {
            App application = new App();
        }

        SomePage page = new SomePage();

Ответ 4

На самом деле вы можете использовать одно и то же приложение, и если ресурсы из одной сборки, вы должны вызвать методы InitializeComponents, чтобы заставить его работать (Источник здесь).

Приятного дня!