2010-09-14 6 views
14

Also ich habe diese nette kleine MVVM-Lösung, und die Dinge funktionieren großartig. Ich habe ein Ansichtsmodell für eine Kopfzeile, die das Symbol basierend auf dem Status der Anwendung usw. anpasst. Ich habe Akzeptanztests durchgeführt, das Ansichtsmodell funktioniert großartig.Pack Urls und Unit Testing. Problem mit meiner Umgebung?

So möchte ich Komponententest das Verhalten dieses Ansichtsmodells. Ich erstelle mein Unit-Test-Projekt, füge einen neuen Unit-Test für das View-Modell hinzu und schreibe einen einfachen Smoke-Test. (d. h. gegebene verspottete Abhängigkeiten, wird die Klasse instanziiert).

Bam, kein

Allerdings funktioniert die Klasse gut, wenn normal lief. Bei einer weiteren Untersuchung wird mein Fehler wie folgt:

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

So nach dem Call-Stack ich zu dem Schluss kommen, dass meine Packung URLs verwendet, um Ressourcenströme die die Fehler diejenigen sind zu laden treten.

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

(Hinweis: Operations.Shell ist die Assemblierung-Name, /Media/Images/User_Normal.png ist der Image-Pfad/Name, und diese Packung url in der Praxis funktioniert.)

Ist die Packung url Ich habe für my User_Normal.png, die Datei existiert, die Ressource ist richtig in die Baugruppe gepackt (mit Reflektor geprüft).

Das Problem ergibt sich aus der Klasse System.Uri nicht in der Lage, die Pack-URL zu interpretieren. Hier verliere ich mich. Warum würde das nicht in den Grenzen des Testens funktionieren? Ich habe alle WPF Baugruppen in meinem Test-Projekt verwiesen:

  • Windows
  • PresentationCore
  • PresentationFramework
  • System.Xaml

Was bin ich?

aktualisiert

Ordnung so war das ursprüngliche Problem, dass die UriHandler nicht für Pack Urls registriert wurden. (Danke an Julien Lebosquain) Nun, da das behoben ist, hat es immer noch Probleme.

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() 

Es sieht aus wie der Versuch Rudel URL zu etwas webbasiertes für eine Assembly Pack URL zu lösen? Sieht so aus, als ob der HF die Anfrage falsch weitergeleitet hat? Oder fehlt mir etwas?

+0

@Downvoter, haben Sie einen Grund? – Aren

Antwort

16

habe ich dieses Problem einmal zu gebissen ...

die Baugruppen Referenzierung ist nicht genug. WPF muss System.UriParser.Register() mit seinem eigenen URI-Parser aufrufen, damit System.Uri Pack-URLs interpretieren kann.

Reflektieren sagt uns, dass dies vom statischen Konstruktor System.IO.Packaging.PackUriHelper getan wird. Rufen Sie eine beliebige Methode dieser Klasse in Ihrem Test auf, z. B. PackUriHelper.Create(), um sicherzustellen, dass der URI-Parser ordnungsgemäß registriert ist. Art von hässlich, aber sollte funktionieren.

+0

@Julien Lebosquain - Du hattest recht (+1), aber es gibt immer noch Probleme. Weitere Informationen finden Sie im aktualisierten Abschnitt im ursprünglichen Post. Hattest du dieses Problem auch? – Aren

+2

Gelöst es. Es gab mehr für das WPF-Framework, das eine Initialisierung zum Hinzufügen eines URL-Präfix-Handlers zu WebRequest/WebResponse benötigte. Am Ende habe ich ein 'FrameworkElement'-Objekt instantiiert, das über statische Konstruktoren genug von dem Framework zu laden schien. – Aren

+2

Das Erstellen eines FrameworkElement startet den gleichen Prozess wie das Erstellen Ihrer Anwendungsklasse, wird aber wahrscheinlich schneller sein. Gut zu wissen! –

1

Ich denke, Sie können das beheben, indem Sie eine Instanz Ihrer Hauptanwendungsklasse erstellen, bevor Sie irgendwelche Tests ausführen. Dies wird die Handler verkabeln, die Julien in der anderen Antwort erwähnt.

+0

Ich möchte meine Anwendung lieber nicht testen, um Komponenten zu testen. – Aren

2

Ein kleines Codebeispiel, das zu den obigen Antworten hinzugefügt werden soll. Wir verwenden das Folgende in einem Komponententest, um dieses Problem zu umgehen.

Sobald dies beim Teststart aufgerufen wurde, funktioniert alles einwandfrei.

12

Aufbauend auf andere Antworten, hier ist der (NUnit) Code, meine Tests gehen Grün gemacht:

In AssemblyInfo.cs:

[assembly: RequiresSTA] 

in einer eigenen Datei:

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

App ist meine Hauptanwendungsklasse. Jede Klasse in der relevanten Assembly wird das vermutlich tun.

+0

Hat der Trick für mich auch in meinen Tests; Vielen Dank! –