Unit Testing WPF Application with siteoforigin pac

2020-07-14 05:52发布

问题:

I have some unit tests that I'm writing for a WPF application, and as much as I've tried to avoid it, I have some code under test that instantiates a View. As soon as the view is instantiated, all the markup extensions, styles, etc are evaluated. To resolve this I've created a dummy Application and registered any required resources when the test assembly is initialized:

[TestClass]
public class AssemblyInitialize
{
    [AssemblyInitialize]
    public static void SetupTestAssembly(TestContext context)
    {
        if (Application.Current == null)
            new Application();

        var resources = new List<string>
            {
              "pack://application:,,,/AssemblyName;component/ResourceDictionary.xaml"
            };

       foreach(var resource in resources)
       {
           var uri = new Uri(resource);
           var dictionary = new ResourceDictionary { Source = uri };
           Application.Current.Resources.MergedDictionaries.Add(dictionary);
       }
    }
}

I've used this approach in the past, and it works ok.

I've run into a small snag with this approach. I have a few resources that use pack://siteoforigin: in the pack Uri, and when the tests instantiate this view I get an error about not being able to resolve the file.

The XAML:

<ResourceDictionary
   xmlns="...">

   <ImageBrush 
      x:Key="ResourceName"
      ImageSource="pack://siteoforigin:,,,/Resources/image.png" 
      />
</ResourceDictionary>

Error Message:

 Could not find a part of the path 'C:\\Solution\\TestResults\\Workspace_2012-03-01 14_54_29\\Resources\\image.png'

I've added the Resources directory as a deployment item, and I've confirmed that the image is the TestRun output directory. It seems that the AppDomain is operating one folder above where the location of my test assemblies, because the file is actually located at:

c:\Solution\TestResults\Workspace_2012-03-01 14_54_29\ Out \Resources\image.png

Any suggestions on how I can get the WPF Application to use the Out directory as it's primary folder?

回答1:

This is because the AppDomain.BaseDirectory that is setup by your test runner doesn't have a trailing '/' character, this causes the code that resolves siteoforigin paths to lose the last directory in the path.

You can check this by looking at the result of the following code when running normally or in tests.

Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory);

This has been recently fixed in NUnit (included in 2.6), but may still be an issue with other test runners.

If you're interested this is the equivalent of what the siteoforigin code is doing:

new Uri(new Uri(baseDirectory), "some/relative/path.jpg").LocalPath

Try that with and without a trailing slash in baseDirectory.