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?
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
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();
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With