I have a StringTable.xaml in my WPF project, with <system:String x:Key="IDS_DATA_HEADER_TIMED_TEST_RECORD_NUMBER">Record Number</system:String>
. My model makes use of this StringTable, with public static string foobar = (string)Application.Current.FindResource("PLACEHOLDER_TEXT");
Thus, I cannot Unit Test my model in MSTest without it being aware of xaml.
This question fills a niche because many questions about xaml are how to unit to the GUI. Yes, good practice is to use the MVVM pattern to separate model from GUI, and only test the model. Yes, I probably have the model too tightly coupled to the GUI framework, and so I will not be able to easily switch from WPF to some other.
In my unit tests, if I try to use a function which uses StringTable.xaml, I noticed any one of three errors:
System.Windows.ResourceReferenceKeyNotFoundException: 'PLACEHOLDER_TEXT' resource not found.
or
Null pointer exception when I try to use the variable foobar
or
Casting / Conversion error when trying to cast the unfound resource to string with (string)Application.Current.FindResource("PLACEHOLDER_TEXT");
For clarification, StringTable.xaml is added as a merged dictionary within my App.xaml file:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="PlaceholderNamespace/SomeStyles.xaml"/>
<ResourceDictionary Source="PlaceholderNamespace/NumberTable.xaml"/>
<ResourceDictionary Source="PlaceholderNamespace/StringTable.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
I have followed Wesley's post in a similar Stack Overflow and added (code snippet exactly duplicated):
var app = new App(); //magically sets Application.Current
app.InitializeComponent(); //parses the app.xaml and loads the resources
to the top of my tests. This works well when running one unit test at a time. If I try to run multiple unit tests sequentially, however, I recieve the error:
Cannot create more than one System.Windows.Application instance in the same AppDomain
Thus, I have to run each unit test. One. At. A. Time. This is annoying, so I will either start shoving all of my testing code into as few tests as possible (which kind of defeats the purpose), or run them less frequently than I should because it takes so long to get thru my test suite (which kind of defeats the purpose). If I only have it at the top of the first unit test in a sequence, I noticed the previously stated errors. This implies that the resources seemed to unload after the first test. But the AppDomain is still there.
I use MSTest, but have read that NUnit also suffers the same issue of not creating new app domains. Jeremy Wiebe's answer to a Stack Overflow about MSTest mentions that creating a new AppDomain is expensive. This would answer why it is not created more than once, but not how to get around this for my case.
Interestingly, I actually see the first test succeed while the second one is processing. When both tests complete, they will both fail. It's as if a test can retroactively fail because the app domain tried to change.
Anyone know how I can load all the StringTable.xaml resources into Application.Current, and have it persist through all unit tests in a sequence?