9

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?

Community
  • 1
  • 1
ford
  • 1,839
  • 3
  • 20
  • 38
  • Why is the markup going to be part of your unit tests? – Erik Dietrich Feb 02 '12 at 23:03
  • I am using my current method primarily because this is the only way that I know of to test the constructors I have made for this class (which inherits from Page). I am open to other options. – ford Feb 02 '12 at 23:10
  • 1
    [This question](http://stackoverflow.com/questions/747166/testing-a-wpf-window-with-staticresources) actually provides a solution for this problem. – Grochni Sep 05 '14 at 06:23

3 Answers3

7

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();
Community
  • 1
  • 1
Maslow
  • 18,464
  • 20
  • 106
  • 193
7

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.

Erik Dietrich
  • 6,080
  • 6
  • 26
  • 37
  • Alright, looks like the answer is "don't put so much code in code-behind that unit tests are necessary". I'll move my excess code out of the xaml.cs files and test those parts separate, getting closer to MVVM standards. – ford Feb 03 '12 at 16:26
5

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
Wesley
  • 61
  • 1
  • 2