2009-10-09 20 views
6

Im Rahmen eines Unit-Test-IMocking FormsIdentity.Ticket.UserData mit Moq

Nachstehend ist der Rückgabewert von FormsIdentity.Ticket.UserData zu verspotten versuche wird nicht funktionieren, aber es sollte eine Vorstellung davon, was ich bin versuchen zu tun:

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

der Code, den ich zu Test versuchen etwas wie folgt aussieht:

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

Alles, was ich in meinem Unit-Test machen will, ist der Rückgabewert von FormsIdentity.Ti Fälschung cket.UserData. Aber wenn ich den Code im ersten Abschnitt ausführe, erhalte ich einen Fehler, wenn ich versuche, die FormsIdentity zu verspotten. Der Fehler besagt, dass der zu überspielende Typ eine Schnittstelle, eine abstrakte Klasse oder eine nicht versiegelte Klasse sein muss.

Ich habe versucht, IIdentity anstelle von FormsIdentity zu verwenden (FormsIdentity ist eine Implementierung von IIdentity) aber IIdentity nicht .Ticket.UserData.

Also wie kann ich diesen Test schreiben, so dass ich einen Wert von FormsIdentity.Ticket.UserData bekomme?

+0

die Methode Stellt sich heraus, ich wurde zu Test versucht wurde zu viel zu tun. Es verletzte das Muster der Verantwortlichkeit, das das Testen erschwerte. Ich habe seit der Methode die Methode überarbeitet. Wie für die ursprüngliche Frage - es erscheint nicht, gibt es eine Möglichkeit, FormsIdentity.Ticket.UserData zu mokieren, da es Teil einer Klasse ist, die versiegelt ist – codette

Antwort

0

Ich bin kein Unit-Test-Experte, auf jeden Fall nur meine Füße in der Gegend nass.

Ist es nicht übertrieben, die Identität in einem Komponententest nachzuahmen, weil der Identitätscode Code ist, von dem Sie annehmen können, dass er bereits isoliert arbeitet? (dh es ist Microsofts Code?) Wenn Sie zum Beispiel Ihren eigenen Code testen, müssen Sie keines der Framework-Objekte austricksen. Ich meine, würdest du jemals eine Liste oder ein Wörterbuch spotten müssen?

Wenn Sie wirklich wollen, Ihren Code isoliert zu testen oder aus irgendeinem Grund super feines Steuerelement über die in Userdata zurückgegebenen Daten haben, können Sie nicht einfach eine Schnittstelle für die Interaktion zwischen der Identität und Ihrem Code schreiben ?

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 

hoffe, das hilft

+0

Meine Schuld für den Versuch, die Frage kurz zu halten. Aber das wird für mich nicht funktionieren, da auf die Principal-Identität innerhalb der Methode, die ich testen möchte, zugegriffen wird. Aber Sie haben Recht, dass ich nicht den richtigen Teil meiner Methode teste – codette