Wie zum Hohn Pfad der Anwendung beim unit-testing, Web App
Ich bin testen von code in einer MVC-HTML-helper wirft einen Fehler, wenn Sie versuchen, um die Anwendung Pfad:
//appropriate code that uses System.IO.Path to get directory that results in:
string path = "~\\Views\\directory\\subdirectory\\fileName.cshtml";
htmlHelper.Partial(path, model, viewData); //exception thrown here
Ausnahme, die geworfen wird, ist
System.Web.HttpException: Die Anwendung der relativen virtuellen Pfad " ~/Views/Verzeichnis/Unterverzeichnis/Dateiname.cshtml " nicht verabsolutiert werden, da der Pfad zu der Anwendung, ist nicht bekannt.
Anschluss an die Beratung der Wie zu beheben Problem mit dem image-Pfad bei der Prüfung HtmlHelper?
Ich habe vorgetäuscht (mit Moq):
Request.Url
um einen string zurückzugeben, derRequest.RawUrl
um einen string zurückzugeben, derRequest.ApplicationPath
um einen string zurückzugeben, derRequest.ServerVariables
null zurück, NameValueCollectionResponse.ApplyAppPathModifier(string virtualPath)
um einen string zurückzugeben, der
Was sonst noch notwendig ist, in der Lage sein, damit dieser code ausgeführt werden, der im Rahmen eines unit-test ausgeführt?
Oder
Was andere Ansatz sollte ich nehmen für die Darstellung einer Teilansicht auf eine dynamisch erstellte Zeichenfolge?
- Es ist nicht eine vollständige Antwort auf deine Frage, aber wenn Sie Ihre Mocks erstellt werden, wie
new Mock<I....>(MockBehavior.Strict)
erhalten Sie ASP.NET MVC und Moq Ihnen sagen, was Sie brauchen - Sie bekommen Ausnahmen für setups, die Sie noch nicht umgesetzt. - Danke @Ciaran, ist es nützlich zu wissen, aber es scheint, ich habe verspottet alles, was notwendig für
MockBehavior.Strict
mir zu erlauben, führen Sie den test auf der Linie werfen der Ausnahme. - Ich in der Regel nicht unit-testen Sie den rendering-Prozess. Was denken Sie über ein "pass" auf diesem Gerät testen?
- Der test ist für den Bau von diesem Weg, aber ich nehme an, dass das sollte sein gelegt in eine helper-Klasse und dort getestet.
- wenn Sie möchten, ansehen für eine Frage, die Sie dazu aufgefordert werden einige gute Gummi-ducking (c2.com/cgi/wiki?RubberDucking), bitte beantworten Sie unten und erhalten Sie einen upvote und eine akzeptierte Antwort.
- Lustig ist, dass ich gebeten wurde, eine Ente, die in einem völlig anderen Kontext nur dieses Wochenende 🙂 ich bin froh, dass ich helfen konnte.
- Sie können versuchen, die Lösung hier: blog.jardalu.com/2013/4/23/...
- die blog-post-URL ist die Rückkehr 404
- Ich kopierte archivierter blog-Inhalte als separate Antwort.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Als alternative zum mocking eingebaut .net-Klassen können Sie
Verwenden Sie die oben-Klasse, um absolute Pfade.
Und für Für unit-Tests können Sie spotten und injizieren eine Implementierung von IPathProvider, die Arbeit in der unit-testing-Umgebung.
--AKTUALISIERTEN CODE
DefaultPathProvider
eine Klasse, in der die MVC-Bibliothek, die bereits implementiertIPathProvider
?Für was es Wert ist, ich rannte gegen den gleichen Fehler und folgte ihm durch die
System.Web
Quelle zu finden, es tritt auf, weilHttpRuntime.AppDomainAppVirtualPathObject
null ist.Dies ist eine unveränderliche Eigenschaft der HttpRuntime-singleton ist, wird wie folgt initialisiert:
wo der Schlüssel ist
".appVPath"
. d.h. es kommt aus der Anwendungsdomäne. Könnte es möglich sein, zu fälschen es mit:Aber ehrlich gesagt der Ansatz in der akzeptierten Antwort klingt viel besser als mucking um mit der AppDomain.
AppDomain.CurrentDomain.SetData(".appDomain", "*"); AppDomain.CurrentDomain.SetData(".appVPath", "/appbase");
Ich bin auch eine Lösung von einem blog-post, die nicht mehr verfügbar ist (http://blog.jardalu.com/2013/4/23/httprequest_mappath_vs_httpserverutility_mappath)
Komplette code: http://pastebin.com/ar05Ze7p
Der Versuch zu machen, Teile der ASP.NET gerne mit verschiedenen Arten von tests scheint, für mich, ziemlich zerbrechlich. Und ich bin geneigt zu glauben, dass der Spott route funktioniert nur, wenn man grundsätzlich vermeiden, mit ASP.NET oder MVC und stattdessen schreiben Sie Ihre eigenen webserver, von Grund auf.
Stattdessen verwenden Sie einfach
ApplicationHost.CreateApplicationHost
zu erstellen Sie eine korrekt initialisierteAppDomain
. Dann führen Sie Ihre test-code aus, dass die domain mitAppDomain.DoCallback
.Hinweis: wenn Sie versuchen, diese, mich selbst, meine test-runner-code wurde in einer gesonderten Versammlung von der
WebAppRoot/bin
- Verzeichnis. Dies ist ein Problem, weil, wennHostApplication.CreateApplicationHost
erstellt eine neueAppDomain
, setzt es den base-directory zu so etwas wie IhremWebAppRoot
- Verzeichnis. Daher, Sie muss definierenAppDomainUnveiler
in einer Versammlung, die sichtbar ist in derWebAppRoot/bin
Verzeichnis (so muss es sein in Ihre webapp Codebasis und kann nicht gelagert werden separat in einem Test-assembly, leider). Ich schlage vor, dass, wenn Sie möchten, können Sie Ihre test-code in einer separaten assembly, die Sie abonnieren SieAppDomain.AssemblyResolve -
inAppDomainUnveiler
's Konstruktor. Sobald Sie Ihre Prüfung Montage wird dieAppDomain
Objekt, es könnenAppDomain.SetData
zu übergeben, zusammen mit Informationen darüber, wo das laden der Test-Baugruppe. Dann ist deinAssemblyResolve
Abonnent kannAppDomain.GetData
um zu entdecken, wo das laden der test-assembly aus. (Ich bin mir nicht sicher, aber die Art von Objekten Sie könnenSetData
/GetData
könnte, Recht begrenzt zu sein—ich habe gerade verwendetstring
s mir selbst sicher zu sein). Das ist ein bisschen ärgerlich, aber ich denke, es ist der beste Weg, um separate Bedenken in dieser situation.