2010-03-29 11 views
5

Sto scrivendo alcuni test unitari per un metodo di estensione che ho scritto su IPrincipal. Per aiutare, ho creato un paio di classi di supporto (un codice per i membri non-implementate delle interfacce è stato omesso per brevità):Come si crea uno stub di test delle unità per un'interfaccia contenente un membro di sola lettura?

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!!! 
} 

Tuttavia, la proprietà Name nell'interfaccia IIdentity è di sola lettura (l'interfaccia IIDentity specifica un getter ma non un setter per la proprietà Name).

Come posso impostare la proprietà Name nel mio oggetto stub a scopo di test se l'interfaccia lo ha definito come una proprietà di sola lettura?

+0

Costruttore? i.e 'IIdentityStub' avrà un costruttore parametrizzato che accetta Nome come parametro. – shahkalpesh

+0

Il tuo "BZZZT" si riferisce a un errore di compilazione? Sono stato in grado di compilare il tuo campione bene (con un punto e virgola sulla proprietà Identity, ovvero). – micahtan

+0

@micahtan: Sì, ma quando provate a scrivere un test contro di esso e impostate il valore di 'Name' nel test, il compilatore si lamenterà che' Name' è di sola lettura, perché la proprietà 'Name' in' IIDentity' non ha un setter definito. –

risposta

3

Si sta utilizzando la funzione di auto-proprietà di C#, ma si dovrebbe andare sulla rotta manuale e creare un campo di supporto per la proprietà. Una volta che hai un campo di supporto, puoi impostarne il valore nel costruttore (o renderlo un campo pubblico e impostarlo dopo aver ottenuto l'oggetto, ma questo è un po 'più brutto).

public class IIdentityStub : IIdentity{ 
    private string _name; 

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

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

E se il valore non è impostabile tramite il costruttore, si è verificato un problema con il progetto. –

+0

Eccellente, grazie. –

+0

@Robert Harvey: nessun problema signore. –

1

mi consiglia di utilizzare una libreria Mock come NMock

+1

Vero, ma ho pensato che sarebbe meglio imparare come scrivere prima i miei stub. –

2

Sono d'accordo con juharr - utilizzare un quadro di scherno/isolamento. Io raccomanderei lo Moq.

Quanto segue stampa "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: Ma se si vuole farlo 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; } 
    } 
} 

(Quanto sopra è non un unit test, solo un esempio di stub laminati a mano usando un po 'di iniezione di dipendenza.)

Problemi correlati