Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make Unit Tests aware of Application.Resources

I have a ResourceDictionary included in my Application.Resources area of my WPF project. This

From App.xaml (in the manner of this SO response):

App.xaml:

<Application.Resources>    
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>                
            <ResourceDictionary 
                  Source="MyDictionary.xaml">
                </ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Within this dictionary, I have several styles, including a Page style:

MyDictionary.xaml:

<SolidColorBrush x:Key="PageBackgroundBrush" 
                     Color="Black" />

<Style x:Key="PageStyle" TargetType="Page">
        <Setter Property="Background" Value="{StaticResource ResourceKey=PageBackgroundBrush}" />
        <Setter Property="Height" Value="Auto" />
        <Setter Property="Width" Value="Auto" />
    </Style>

MyPage.xaml:

<Page x:Class="MyProject.MyPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="250"
      Title="Page"
      Style="{StaticResource ResourceKey=PageStyle}"
      >
<Grid>
</Grid>
</Page>

MyPage.xaml.cs

public class MyPage : Page
{
    public MyPage() 
    {
        // this part crashes during unit tests because 'PageStyle' was not found
        InitializeComponent();
    }
}

This setup works quite well both when Visual Studio views the page in design mode and when running the project.

I am using Visual Studio's built in Unit Test tools . When I attempt to make unit tests for the MyPage class (which uses MyPage.xaml when the constructor fires) my tests fail. MyPage.xaml makes use of the styles defined in the dictionary included in Application.Resources. The tests do not recognize the PageStyle, because Application.Resources was not included when the unit test began, and as a result the page fails to instantiate. How do I include my Application.Resources in my unit tests? Alternatively, is there a better way to run unit tests for WPF pages and windows?

like image 222
ford Avatar asked Feb 02 '12 22:02

ford


3 Answers

It seems that creating an instance of the application class and calling InitializeComponent does the trick.

var app = new App(); //magically sets Application.Current
app.InitializeComponent(); //parses the app.xaml and loads the resources
like image 95
Wesley Avatar answered Nov 16 '22 19:11

Wesley


I've worked out some code that works and actually loads the real item that was missing for me, although the approach https://stackoverflow.com/a/748440/57883 is probably better for isolating test errors and building up the testing library.

var targetAssembly = typeof(PracticeManagement.MainWindow).Assembly;
var currentAssembly = this.GetType().Assembly;

Application.ResourceAssembly = targetAssembly;

var rd = (ResourceDictionary)Application.LoadComponent(new Uri("/ProjectName;component/CommonUIStylesDictionary.xaml", UriKind.Relative));

if (Application.Current == null)
{
    var x = new System.Windows.Application(); // magically is assigned to application.current behind the scenes it seems
}

Application.Current.Resources = rd;

var mainWindow = new ProjectName.MainWindow(this.Connection.ConnectionString);

mainWindow.Show();
like image 41
Maslow Avatar answered Nov 16 '22 20:11

Maslow


Based on your comment, I would suggest that you use Model-View-ViewModel (MVVM) or any other scheme to pull as much logic as possible out of your GUI-level components, and testing that logic there. It doesn't directly solve your current problem, but the fact is that GUI logic is notoriously difficult to test - so difficult as not to be worth it, in my opinion, with MS Test and other unit test runners.

Unit testing the GUI is a world of pain (I've tried). There are generally better tools for this.

like image 7
Erik Dietrich Avatar answered Nov 16 '22 19:11

Erik Dietrich