2009-10-09 21 views
6

Como parte de una unidad de prueba que estoy tratando de burlarse del valor de retorno de FormsIdentity.Ticket.UserDataque imita FormsIdentity.Ticket.UserData con Moq

El siguiente no funcionará pero debería dar una idea de lo que soy tratando de hacer:

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

el código que estoy tratando de prueba se ve algo como esto:

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

Todo lo que quiero hacer en mi unidad de prueba es falso el valor de retorno de FormsIdentity.Ti cket.UserData. Pero cuando ejecuto el código en la primera sección, aparece un error al intentar simular el FormsIdentity. El error dice que el tipo para simular debe ser una interfaz, clase abstracta o clase no sellada.

Intenté usar IIdentity en lugar de FormsIdentity (FormsIdentity es una implementación de IIdentity) pero IIdentity no tiene .Ticket.UserData.

Entonces, ¿cómo puedo escribir esta prueba para que obtenga un valor de FormsIdentity.Ticket.UserData?

+0

Resulta que el método que estaba tratando de prueba estaba haciendo demasiado. Violaba el patrón de responsabilidad individual que dificultaba la prueba. Desde entonces he refactorizado el método. En cuanto a la pregunta original, no parece que haya ninguna forma de burlarse de FormsIdentity.Ticket.UserData, ya que es parte de una clase que está sellada – codette

Respuesta

0

No soy un experto en Test Unit, de ninguna manera, solo me mojo los pies en el área.

¿No es exagerado burlarse de la identidad en una prueba de unidad, porque el código de identidad es un código que puede asumir que funciona de manera aislada? (es decir, ¿es el código de Microsoft?) Por ejemplo, cuando la unidad prueba su propio código, no necesitaría burlarse de uno de los objetos del Framework. Quiero decir, ¿alguna vez necesitarías burlarte de una Lista o un Diccionario?

Dicho esto, si REALMENTE desea probar su código de forma aislada o por algún motivo tener un control superfino sobre los datos devueltos en Userdata, no puede simplemente escribir una interfaz para la interacción entre la identidad y su código ?

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 

Esperanza esto ayuda

+0

Mi error por tratar de mantener la pregunta sucinta. Pero esto no funcionará para mí ya que se está accediendo a la identidad del Principal dentro del método que estoy tratando de probar. Pero tienes razón en que no estoy probando la parte correcta de mi método – codette

Cuestiones relacionadas