2009-10-09 15 views
6

W ramach testów jednostkowych próbuję mock wartość zwracaną FormsIdentity.Ticket.UserDataMocking FormsIdentity.Ticket.UserData z Min

Poniższa nie będzie działać, ale powinien dać wyobrażenie o tym, co ja próbuje zrobić:

var principal = Mock<IPrincipal>(); 
var formsIdentity = Mock<FormsIdentity>(); 
formsIdentity.Setup(a => a.Ticket.UserData).Returns("aaa | bbb | ccc"); 
principal.Setup(b => b.Identity).Returns(formsIdentity.Object); 

Kod próbuję testu wygląda mniej więcej tak:

FormsIdentity fIdentity = HttpContext.Current.User.Identity as FormsIdentity; 
string userData = fIdentity.Ticket.UserData; 

Wszystko chcę zrobić w moim badanej jednostki jest fałszywy wartość zwracana z FormsIdentity.Ti cket.UserData. Ale kiedy uruchamiam kod w pierwszej sekcji, pojawia się błąd przy próbie wyśmiewania FormsIdentity. Błąd mówi, że typem do sfałszowania musi być interfejs, klasa abstrakcyjna lub klasa niezapieczętowana.

Próbowałem użyć IIdentity zamiast FormsIdentity (FormsIdentity jest implementacją IIdentity), ale IIdentity nie ma .Ticket.UserData.

Więc jak mogę napisać ten test tak, aby uzyskać wartość od FormsIdentity.Ticket.UserData?

+0

Okazuje się metodę Próbowałem testu robił zbyt wiele. To naruszało wzór odpowiedzialności, który utrudniał testowanie. Od tamtej pory refaktoryzowałem metodę. Co do pierwotnego pytania - nie wydaje się, że jest jakiś sposób, aby drwić FormsIdentity.Ticket.UserData ponieważ część klasy, która jest uszczelniona – codette

Odpowiedz

0

Nie jestem ekspertem Test jednostki, za pomocą wszelkich środków, po prostu coraz nogi mokre w okolicy.

Czy to nie przesada wyśmiewać się tożsamości w badanej jednostki, ponieważ kod identyfikacyjny jest kod, który można założyć już prace w izolacji? (to jest kod Microsoftu?) Na przykład, gdy jednostka testuje twój własny kod, nie musiałbyś wyśmiewać jednego z obiektów Framework. Mam na myśli, czy kiedykolwiek będziesz musiał sfałszować listę lub słownik?

W związku z tym, jeśli NAPRAWDĘ chcesz przetestować swój kod w izolacji lub z jakiegoś powodu uzyskasz super dokładną kontrolę nad danymi zwróconymi w Userdata, nie możesz po prostu napisać interfejsu interakcji między Tożsamością a kodem ?

Public Interface IIdentityUserData 
    Readonly Property UserData As String 
End Interface 

Public Class RealIdentityWrapper 
Implements IIdentityUserData 

Private _identity as FormsIdentity 
Public Sub New(identity as FormsIdentity) 
    'the real version takes in the actual forms identity object 
    _identity = identity 
End Sub 
Readonly Property UserData As String Implements IIDentityUserData.UserData 
    If not _identity is nothing then 
     Return _identity.Ticket.UserData 
    End If 
End Property 
End Class 

'FAKE CLASS...use this instead of Mock 
Public Class FakeIdentityWrapper 
Implements IIdentityUserData 


Readonly Property UserData As String Implements IIDentityUserData.UserData 
    If not _identity is nothing then 
      Return "whatever string you want" 
    End If 
End Property 
End Class 



'here's the code that you're trying to test...modified slightly 
Dim fIdentity As FormsIdentity= HttpContext.Current.User.Identity 
Dim identityUserData As IIdentityUserData 

identityUserData = 
'TODO: Either the Real or Fake implementation. If testing, inject the Fake implementation. If in production, inject the Real implementation 

Dim userData as String 
userData = identityUserData.UserData 

Nadzieja to pomaga

+0

moja wina, starając się pytanie zwięzłe. Ale to nie zadziała, ponieważ dostęp do głównej tożsamości jest możliwy w ramach metody, którą próbuję przetestować. Ale masz rację, że nie testuję właściwej części mojej metody – codette