2010-03-29 6 views
5

Estoy escribiendo algunas pruebas de unidad para un método de extensión que he escrito en IPrincipal. Para ayudar, he creado un par de clases de ayuda (algo de código para los miembros no implementados de las interfaces se ha omitido por razones de brevedad):¿Cómo se crea un apéndice de pruebas unitarias para una interfaz que contiene un miembro de solo lectura?

public class IPrincipalStub : IPrincipal 
{ 
    private IIdentity identityStub = new IIdentityStub(); 

    public IIdentity Identity 
    { 
     get { return identityStub; } 
     set { identityStub = value; } 
    } 
} 

public class IIdentityStub : IIdentity 
{ 
    public string Name { get; set; } // BZZZT!!! 
} 

Sin embargo, la propiedad Name en la interfaz IIdentity es de sólo lectura (la interfaz IIDentity especifica un getter pero no un setter para la propiedad Name).

¿Cómo puedo establecer la propiedad Name en mi objeto de stub para fines de prueba si la interfaz lo ha definido como una propiedad de solo lectura?

+0

Constructor? es decir, 'IIdentityStub' tendrá un constructor parametrizado que tome Name como parámetro. – shahkalpesh

+0

¿Su "BZZZT" se refiere a un error de compilación? Pude compilar su muestra muy bien (con puntos y comas en la propiedad Identity, eso es). – micahtan

+0

@micahtan: Sí, pero cuando intenta escribir una prueba en su contra, y establece el valor de 'Name' en la prueba, el compilador se quejará de que' Name' es de solo lectura, porque la propiedad 'Name' en' IIDentity' no tiene un setter definido. –

Respuesta

3

Está utilizando la función de propiedades automáticas de C#, pero en su lugar debe ir por la ruta manual y crear un campo de respaldo para la propiedad. Una vez que tenga un campo de respaldo, puede establecer su valor en el constructor (o hacerlo un campo público y configurarlo después de que tenga el objeto, pero esto es un poco más feo).

public class IIdentityStub : IIdentity{ 
    private string _name; 

    public IIdentityStub(string name){ 
     _name = name; 
    } 

    public string Name { get { return _name; } } 
} 
+0

Y si el valor no es configurable a través del constructor, tiene un problema con su diseño. –

+0

Excelente, gracias. –

+0

@Robert Harvey: No hay problema, señor. –

1

recomiendo el uso de una biblioteca Mock como NMock

+1

Cierto, pero pensé que sería mejor que aprendiera cómo escribir mis propios stubs primero. –

2

Estoy de acuerdo con juharr - utilizar un marco de burla/aislamiento. Yo recomendaría Moq.

Lo siguiente imprimirá "Robert":

using System; 
using System.Security.Principal; 
using Moq; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main() 
     { 
      var mockIdentity = new Mock<IIdentity>(); 
      var mockPrincipal = new Mock<IPrincipal>(); 

      mockIdentity.SetupGet(x => x.Name).Returns("Robert"); 
      mockPrincipal.SetupGet(x => x.Identity).Returns(mockIdentity.Object); 

      IPrincipal myStub = mockPrincipal.Object; 

      Console.WriteLine(myStub.Identity.Name); 
     } 
    } 
} 

EDIT: Pero si quieres hacerlo a mano ...

using System; 
using System.Security.Principal; 

namespace ConsoleApplication2 
{ 
    class Program 
    { 
     static void Main() 
     { 
      IIdentity identity = 
       new IdentityStub 
        { 
         Name = "Robert", 
         AuthenticationType = "Kerberos", 
         IsAuthenticated = true 
        }; 

      IPrincipal principal = new PrincipalStub(identity); 

      Console.WriteLine(principal.Identity.Name); // Robert 
      Console.WriteLine(principal.IsInRole(PrincipalStub.ValidRole)); // True 
      Console.WriteLine(principal.IsInRole("OtherRole")); // False 
     } 
    } 

    public class PrincipalStub : IPrincipal 
    { 
     public const string ValidRole = "TestRole"; 

     public PrincipalStub(IIdentity identity) 
     { 
      Identity = identity; 
     } 

     public IIdentity Identity { get; private set; } 

     public bool IsInRole(string role) 
     { 
      return role == ValidRole; 
     } 
    } 

    public class IdentityStub : IIdentity 
    { 
     public string Name { get; set; } 
     public string AuthenticationType { get; set; } 
     public bool IsAuthenticated { get; set; } 
    } 
} 

(Lo anterior es no una prueba unitaria, solo un ejemplo de stubs enrollados a mano con un poco de inyección de dependencia.)

Cuestiones relacionadas