Mam serwis internetowy, który próbuję przetestować jednostkowo. W usłudze pobiera kilka HttpContext
podobnych wartości :
m_password = (string)HttpContext.Current.Session["CustomerId"];
m_userID = (string)HttpContext.Current.Session["CustomerUrl"];
w teście jednostkowym tworzę kontekst za pomocą prostego żądania pracownika, na przykład:
SimpleWorkerRequest request = new SimpleWorkerRequest("", "", "", null, new StringWriter());
HttpContext context = new HttpContext(request);
HttpContext.Current = context;
Jednak za każdym razem, gdy próbuję ustawić wartości HttpContext.Current.Session
HttpContext.Current.Session["CustomerId"] = "customer1";
HttpContext.Current.Session["CustomerUrl"] = "customer1Url";
Otrzymuję wyjątek odniesienia zerowego, który mówi, że HttpContext.Current.Session
jest zerowy.
Czy jest jakiś sposób na zainicjowanie bieżącej sesji w ramach testu jednostkowego?
Odpowiedzi:
Musieliśmy kpić
HttpContext
, używającHttpContextManager
i dzwoniąc do fabryki z poziomu naszej aplikacji, a także testów jednostkowychMożna by potem zastąpić żadnych połączeń do
HttpContext.Current
zHttpContextManager.Current
oraz mieć dostęp do tych samych metod. Następnie podczas testowania możesz uzyskać dostęp doHttpContextManager
swoich oczekiwań i kpić z nichOto przykład z wykorzystaniem Moq :
a następnie, aby użyć go w testach jednostkowych, nazywam to w ramach mojej metody Init Init
następnie możesz w powyższej metodzie dodać oczekiwane wyniki z sesji, które mają być dostępne dla Twojego serwisu internetowego.
źródło
HttpContextManager
byłoby lepsze imię,HttpContextSource
ale zgadzam się, żeHttpContextFactory
jest mylące.Możesz go „sfałszować”, tworząc nowy
HttpContext
taki:http://www.necronet.org/archive/2010/07/28/unit-testing-code-that-uses-httpcontext-current-session.aspx
Wziąłem ten kod i umieściłem go w statycznej klasie pomocniczej w następujący sposób:
Lub zamiast używać refleksji do budowy nowej
HttpSessionState
instancji, możesz po prostu dołączyćHttpSessionStateContainer
ją doHttpContext
(zgodnie z komentarzem Brenta M. Spella):a następnie możesz to nazwać w testach jednostkowych, takich jak:
źródło
Server.MapPath()
nie będzie działać, jeśli użyjesz tego.Rozwiązanie Milox jest lepsze niż zaakceptowane IMHO, ale miałem pewne problemy z tą implementacją podczas obsługi adresów URL za pomocą kwerendy .
Wprowadziłem kilka zmian, aby działał poprawnie z dowolnymi adresami URL i aby uniknąć refleksji.
źródło
httpContext.Session
, jakiś pomysł, jak zrobić to samohttpContext.Application
?Zastanawiałem się nad tym jakiś czas temu.
Testowanie jednostkowe HttpContext.Current.Session w MVC3 .NET
Mam nadzieję, że to pomoże.
źródło
Jeśli używasz frameworka MVC, powinno to działać. użyłem FakeHttpContext firmy Milox i dodałem kilka dodatkowych wierszy kodu. Pomysł przyszedł z tego postu:
http://codepaste.net/p269t8
Wygląda na to, że działa w MVC 5. Nie próbowałem tego we wcześniejszych wersjach MVC.
źródło
Możesz spróbować FakeHttpContext :
źródło
W asp.net Core / MVC 6 rc2 możesz ustawić
HttpContext
rc 1 był
https://stackoverflow.com/a/34022964/516748
Rozważ użycie
Moq
źródło
Odpowiedź, która ze mną zadziałała, jest tym, co napisał @Anthony, ale musisz dodać kolejny wiersz
więc możesz użyć tego:
źródło
Spróbuj tego:
I Dodaj klasę:
Umożliwi to testowanie zarówno sesji, jak i pamięci podręcznej.
źródło
Szukałem czegoś mniej inwazyjnego niż wspomniane powyżej opcje. W końcu wymyśliłem tandetne rozwiązanie, ale może sprawić, że niektórzy ludzie poruszą się trochę szybciej.
Najpierw stworzyłem klasę TestSession :
Następnie dodałem opcjonalny parametr do konstruktora mojego kontrolera. Jeśli parametr jest obecny, użyj go do manipulacji sesją. W przeciwnym razie użyj HttpContext.Session:
Teraz mogę wstrzyknąć moją TestSession do kontrolera:
źródło
Nigdy nie kpij ... nigdy! Rozwiązanie jest dość proste. Po co fałszować takie piękne stworzenie
HttpContext
?Zepchnij sesję w dół! (Tylko ten wiersz jest wystarczający dla większości z nas, ale wyjaśniono go szczegółowo poniżej)
(string)HttpContext.Current.Session["CustomerId"];
właśnie w ten sposób uzyskujemy do niego dostęp Zmień to naPodczas wywoływania z testu _customObject używa alternatywnego magazynu (DB lub wartość klucza w chmurze [ http://www.kvstore.io/] )
Ale kiedy wywoływany z prawdziwej aplikacji,
_customObject
używaSession
.jak to się robi? no cóż ... Wstrzyknięcie zależności!
Test może więc ustawić sesję (pod ziemią), a następnie wywołać metodę aplikacji, tak jakby nic nie wiedziała o sesji. Następnie test potajemnie sprawdza, czy kod aplikacji poprawnie zaktualizował sesję. Lub jeśli aplikacja zachowuje się na podstawie wartości sesji ustawionej przez test.
W rzeczywistości skończyliśmy kpić, chociaż powiedziałem: „nigdy nie kpij”. Ponieważ nie mogliśmy się powstrzymać od przejścia do następnej zasady: „kpij tam, gdzie to najmniej boli!”. Szydzisz z ogromnej,
HttpContext
czy szydzisz z małej sesji, co najmniej boli? nie pytaj mnie, skąd pochodzą te zasady. Powiedzmy tylko zdrowy rozsądek. Oto ciekawa lektura na temat nie kpienia, ponieważ test jednostkowy może nas zabićźródło
Odpowiedź udzielona przez @Ro Hit bardzo mi pomogła, ale brakowało mi poświadczeń użytkownika, ponieważ musiałem sfałszować użytkownika do testów jednostki uwierzytelniającej. Dlatego pozwól mi opisać, jak to rozwiązałem.
Zgodnie z tym , jeśli dodasz metodę
a następnie dołącz
do ostatniego wiersza
TestSetup
metody, którą wykonałeś, poświadczenia użytkownika są dodawane i gotowe do użycia w testach uwierzytelniania.Zauważyłem również, że w HttpContext są inne części, których możesz potrzebować, takie jak
.MapPath()
metoda. Dostępny jest FakeHttpContext, który został opisany tutaj i można go zainstalować za pomocą NuGet.źródło
Znalazłem następujące proste rozwiązanie do określania użytkownika w HttpContext: https://forums.asp.net/post/5828182.aspx
źródło
Spróbuj w ten sposób ..
źródło