Перенос пакетов и модульное тестирование. Проблема с моей средой?

Итак, у меня есть это приятное небольшое MVVM-решение, и все отлично работает. У меня есть модель представления для панели заголовка, которая настраивает значок в зависимости от состояния приложения и т.д. Я выполнил приемочные тесты, модель представления отлично работает.

Итак, я хочу unit test поведение этой модели представления. Я создаю проект модульного тестирования, добавлю новый unit test для модели представления и напишу простую smoke test. (т.е. с учетом смешных зависимостей, будет ли экземпляр класса).

Bam, no

Однако класс работает нормально, когда работает нормально. При дальнейшем осмотре моя ошибка выглядит следующим образом:

TestInitialize threw exception: System.UriFormatException: Invalid URI: Invalid port specified.

Итак, следуя стеку вызовов, я пришел к выводу, что мои URL-адреса пакетов, используемые для загрузки потоков ресурсов, - это те, которые пинают ошибки.

pack://application:,,,/Operations.Shell;component/Media/Images/User_Normal.png

(Примечание: Operations.Shell - это имя сборки, /Media/Images/User_Normal.png - путь/имя образа, и этот пакет url работает на практике.)

Является ли URL-адрес пакета для моего User_Normal.png, файл существует, ресурс правильно упакован в сборку (отмечен рефлектором).

Проблема возникает из класса System.Uri, который не может интерпретировать URL-адрес пакета. Здесь я теряюсь. Почему это не работает в рамках тестирования. У меня есть все сборки WPF, упомянутые в моем тестовом проекте:

  • WindowsBase
  • PresentationCore
  • PresentationFramework
  • System.Xaml

Что мне не хватает?

Обновление

Хорошо, поэтому первоначальная проблема заключалась в том, что UriHandler не был зарегистрирован для пакетов пакетов. (Спасибо Julien Lebosquain) Теперь, когда это исправлено, у него все еще есть проблемы.

TestInitialize threw exception: System.NotSupportedException: The URI prefix is not recognized.

System.Net.WebRequest.Create(Uri requestUri, Boolean useUriBase)
System.Net.WebRequest.Create(Uri requestUri)
MS.Internal.WpfWebRequestHelper.CreateRequest(Uri uri)
System.IO.Packaging.PackWebRequest.GetRequest(Boolean allowPseudoRequest)
System.IO.Packaging.PackWebRequest.GetResponse()
MS.Internal.WpfWebRequestHelper.GetResponse(WebRequest request)
System.Windows.Media.Imaging.BitmapDecoder.SetupDecoderFromUriOrStream(Uri uri, Stream stream, BitmapCacheOption cacheOption, Guid& clsId, Boolean& isOriginalWritable, Stream& uriStream, UnmanagedMemoryStream& unmanagedMemoryStream, SafeFileHandle& safeFilehandle)
System.Windows.Media.Imaging.BitmapDecoder.CreateFromUriOrStream(Uri baseUri, Uri uri, Stream stream, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption, RequestCachePolicy uriCachePolicy, Boolean insertInDecoderCache)
System.Windows.Media.Imaging.BitmapImage.FinalizeCreation()
System.Windows.Media.Imaging.BitmapImage.EndInit()
System.Windows.Media.Imaging.BitmapImage..ctor(Uri uriSource, RequestCachePolicy uriCachePolicy)
System.Windows.Media.Imaging.BitmapImage..ctor(Uri uriSource)
MyFramework.Resources.b__1(Uri u)
MyFramework.Resources.ResourceType`1.Load(String path)
Operations.Shell.AppShell.ViewModels.HeaderViewModel..ctor(IEventAggregator eventAggregator, ISecurityService securityService)
Tests.Shell.AppShell.TestHeaderViewModel.TestInitialize()

Похоже, что URL-адрес пакета пытается решить что-то на основе Интернета для URL-адреса сборщика? Похоже, что обработчик неправильно запросил запрос? Или я что-то упускаю?

Ответ 1

Я тоже укусил эту проблему...

Ссылка на сборки недостаточна. WPF необходимо вызвать System.UriParser.Register() со своим собственным парсером URI, чтобы System.Uri мог интерпретировать URL-адреса пакетов.

Отражение говорит нам, что это делается статическим конструктором System.IO.Packaging.PackUriHelper. Вызовите любой метод этого класса в своем тесте, например PackUriHelper.Create(), чтобы убедиться, что парсер URI хорошо зарегистрирован. Вид уродливый, но должен работать.

Ответ 2

Основываясь на других ответах, здесь код (NUnit), который сделал мои тесты зелеными:

В AssemblyInfo.cs:

[assembly: RequiresSTA]

В собственном файле:

[SetUpFixture]
public class PreTestSetup
{
    [SetUp]
    public void Setup()
    {
        PackUriHelper.Create(new Uri("reliable://0"));
        new FrameworkElement();
        System.Windows.Application.ResourceAssembly = typeof (App).Assembly;
    }
}

Приложение - это мой основной класс приложения. Любой класс в соответствующей сборке будет, предположительно.

Ответ 3

Небольшой образец кода для добавления к приведенным выше ответам. Мы используем следующее в unit test, чтобы обойти эту проблему.

    [AssemblyInitialize]
    public static void MagicHappensHere(TestContext context) {

        PackUriHelper.Create(new Uri("reliable://0"));
    }

Как только это было вызвано при запуске теста, все работает отлично.

Ответ 4

Я думаю, вы можете исправить это, создав экземпляр вашего основного класса приложения перед запуском любых тестов. Это приведет к подключению обработчиков, которые Жюльен упоминает в другом ответе.