Ich habe einen Webdienst, den ich einem Unit-Test unterziehen möchte. Im Dienst werden mehrere Werte aus dem HttpContext
Gleichen abgerufen, so:
m_password = (string)HttpContext.Current.Session["CustomerId"];
m_userID = (string)HttpContext.Current.Session["CustomerUrl"];
Im Unit-Test erstelle ich den Kontext mithilfe einer einfachen Worker-Anfrage wie folgt:
SimpleWorkerRequest request = new SimpleWorkerRequest("", "", "", null, new StringWriter());
HttpContext context = new HttpContext(request);
HttpContext.Current = context;
Wenn ich jedoch versuche, die Werte von einzustellen HttpContext.Current.Session
HttpContext.Current.Session["CustomerId"] = "customer1";
HttpContext.Current.Session["CustomerUrl"] = "customer1Url";
Ich erhalte eine Nullreferenzausnahme, die besagt, dass sie HttpContext.Current.Session
null ist.
Gibt es eine Möglichkeit, die aktuelle Sitzung innerhalb des Komponententests zu initialisieren?
Antworten:
Wir mussten uns verspotten,
HttpContext
indem wir a verwendetenHttpContextManager
und die Fabrik aus unserer Anwendung heraus sowie die Unit-Tests anriefenSie würden dann alle Aufrufe von
HttpContext.Current
durch ersetzenHttpContextManager.Current
und Zugriff auf dieselben Methoden haben. Wenn Sie dann testen, können Sie auch auf die zugreifenHttpContextManager
und Ihre Erwartungen verspottenDies ist ein Beispiel mit Moq :
und um es dann in Ihren Unit-Tests zu verwenden, rufe ich dies in meiner Test Init-Methode auf
Sie können dann in der obigen Methode die erwarteten Ergebnisse aus der Sitzung hinzufügen, von denen Sie erwarten, dass sie für Ihren Webdienst verfügbar sind.
quelle
HttpContextManager
wäre ein besserer Name als,HttpContextSource
aber ich stimme zu,HttpContextFactory
ist irreführend.Sie können es "fälschen", indem Sie ein neues erstellen
HttpContext
wie :http://www.necronet.org/archive/2010/07/28/unit-testing-code-that-uses-httpcontext-current-session.aspx
Ich habe diesen Code genommen und ihn wie folgt in eine statische Hilfsklasse eingefügt:
Oder statt Reflexion mit dem neuen bauen
HttpSessionState
Instanz, können Sie einfach Ihre anhängenHttpSessionStateContainer
auf dieHttpContext
(per Brent M. Spell Kommentar):und dann können Sie es in Ihren Unit-Tests wie folgt aufrufen:
quelle
Server.MapPath()
funktioniert auch nicht, wenn Sie dies verwenden.Die Milox-Lösung ist meiner Meinung nach besser als die akzeptierte, aber ich hatte einige Probleme mit dieser Implementierung beim Umgang mit URLs mit Querystring .
Ich habe einige Änderungen vorgenommen, damit es mit allen URLs richtig funktioniert und Reflection vermieden wird.
quelle
httpContext.Session
, eine Idee zu fälschen , wie Sie dasselbe tun könnenhttpContext.Application
?Ich habe vor einiger Zeit etwas darüber gesagt.
Unit-Test HttpContext.Current.Session in MVC3 .NET
Ich hoffe es hilft.
quelle
Wenn Sie das MVC-Framework verwenden, sollte dies funktionieren. Ich habe Milox ' FakeHttpContext verwendet und ein paar zusätzliche Codezeilen hinzugefügt. Die Idee kam von diesem Beitrag:
http://codepaste.net/p269t8
Dies scheint in MVC 5 zu funktionieren. Ich habe dies in früheren Versionen von MVC nicht versucht.
quelle
Sie können FakeHttpContext ausprobieren :
quelle
Die Antwort, die bei mir funktioniert hat, ist die, die @Anthony geschrieben hat, aber Sie müssen eine weitere Zeile hinzufügen
So können Sie Folgendes verwenden:
quelle
In asp.net Core / MVC 6 rc2 können Sie die einstellen
HttpContext
rc 1 war
https://stackoverflow.com/a/34022964/516748
Erwägen Sie die Verwendung
Moq
quelle
Versuche dies:
Und füge die Klasse hinzu:
Auf diese Weise können Sie sowohl mit der Sitzung als auch mit dem Cache testen.
quelle
Ich suchte nach etwas weniger Invasivem als den oben genannten Optionen. Am Ende habe ich eine kitschige Lösung gefunden, aber es könnte einige Leute dazu bringen, sich etwas schneller zu bewegen.
Zuerst habe ich eine TestSession- Klasse erstellt:
Dann habe ich dem Konstruktor meines Controllers einen optionalen Parameter hinzugefügt. Wenn der Parameter vorhanden ist, verwenden Sie ihn zur Sitzungsmanipulation. Verwenden Sie andernfalls die Datei HttpContext.Session:
Jetzt kann ich meine TestSession in den Controller einspeisen :
quelle
Niemals verspotten ... niemals! Die Lösung ist ziemlich einfach. Warum so eine schöne Kreation vortäuschen?
HttpContext
?Drücken Sie die Sitzung nach unten! (Nur diese Zeile reicht für die meisten von uns aus, um sie zu verstehen, wird aber unten ausführlich erklärt.)
(string)HttpContext.Current.Session["CustomerId"];
So greifen wir jetzt darauf zu. Ändern Sie dies inBeim Aufruf von test verwendet _customObject einen alternativen Speicher (DB- oder Cloud-Schlüsselwert [ http://www.kvstore.io/]). ).
Aber wenn von der realen Anwendung aufgerufen,
_customObject
verwendetSession
.Wie wird das gemacht? gut ... Abhängigkeitsinjektion!
Test kann also die Sitzung (unterirdisch) einstellen und dann die Anwendungsmethode aufrufen, als ob sie nichts über die Sitzung weiß. Testen Sie dann heimlich, ob der Anwendungscode die Sitzung korrekt aktualisiert hat. Oder wenn sich die Anwendung basierend auf dem vom Test festgelegten Sitzungswert verhält.
Eigentlich haben wir uns verspottet, obwohl ich gesagt habe: "Niemals verspotten". Weil wir nicht anders konnten, als zur nächsten Regel überzugehen: "Verspotten, wo es am wenigsten weh tut!". Verspotten Sie sich riesig
HttpContext
oder verspotten Sie eine winzige Sitzung, was am wenigsten schmerzt? Frag mich nicht, woher diese Regeln kommen. Sagen wir einfach gesunden Menschenverstand. Hier ist eine interessante Lektüre über das Nicht-Verspotten, da Unit-Tests uns töten könnenquelle
Die Antwort @Ro Hit gab, hat mir sehr geholfen, aber mir fehlten die Benutzeranmeldeinformationen, weil ich einen Benutzer für das Testen der Authentifizierungseinheit vortäuschen musste. Lassen Sie mich daher beschreiben, wie ich es gelöst habe.
Nach diesem , wenn Sie die Methode hinzufügen
und dann anhängen
bis zur letzten Zeile der
TestSetup
Methode, die Sie abgeschlossen haben, werden die Benutzeranmeldeinformationen hinzugefügt und können für Authentifizierungstests verwendet werden.Mir ist auch aufgefallen, dass in HttpContext möglicherweise andere Teile erforderlich sind, z. B. die
.MapPath()
Methode. Es steht ein FakeHttpContext zur Verfügung, der hier beschrieben wird und über NuGet installiert werden kann.quelle
Ich habe die folgende einfache Lösung zum Angeben eines Benutzers im HttpContext gefunden: https://forums.asp.net/post/5828182.aspx
quelle
Versuchen Sie diesen Weg ..
quelle