2009-06-08 17 views
9

Sto scrivendo un provider di profili personalizzato, ma intendo ancora utilizzare il predefinito AspNetSqlMembershipProvider come provider di appartenenza. Metodo miei GetAllProfiles() nel mio fornitore di profilo assomiglia a questo:Mocking Membership

1 public override ProfileInfoCollection GetAllProfiles(ProfileAuthenticationOption authenticationOption, int pageIndex, int pageSize, out int totalRecords) 
2 { 
3  // Get the profiles 
4  IQueryable<Profile> profiles = _profileRepository.GetAllProfiles(); 
5  
6  // Convert to a ProfileInfoCollection 
7  ProfileInfoCollection profileInfoCollection = new ProfileInfoCollection(); 
8  foreach (Profile profile in profiles) 
9  { 
10   MembershipUser user = Membership.GetUser(profile.UserId); 
11 
12   string username = user.UserName; 
13   bool isAnonymous = false; 
14   DateTime lastActivity = user.LastActivityDate; 
15   DateTime lastUpdated = profile.LastUpdated; 
16 
17   ProfileInfo profileInfo = new ProfileInfo(username, isAnonymous, lastActivity, lastUpdated, 1); 
18 
19   profileInfoCollection.Add(profileInfo); 
20  } 
21 
22  // Set the total number of records. 
23  totalRecords = profiles.ToList().Count; 
24 
25  return profileInfoCollection; 
26 } 

Come faccio a deridere la chiamata Membership.GetUser() in modo che io possa scrivere i test per questo metodo? Qualche suggerimento o esempio? Grazie.

risposta

4

Si può iniettare un'istanza MembershipProvider nel proprio provider di profili e, se nessuna di queste viene iniettata, ricorrere all'utilizzo di Membership.Provider?

public MembershipProvider MembershipProvider 
{ 
    get { return _membershipProvider ?? Membership.Provider; } 
    set { _membershipProvider = value; } 
} 

Il provider del profilo interagirebbe con il provider di appartenenza attraverso il valore restituito da questa proprietà. Nel tuo test iniettavi l'istanza falsa/finta MembershipProvider.

Se si desidera semplicemente prendere in giro i metodi statici su Membership, sarà necessario utilizzare qualcosa come TypeMock, credo.

+0

Sì, stavo pensando di usare TypeMock o Moq, ma non ho visto alcun esempio di questo particolare scenario. Giocherò con un'iniezione mentre suggerivi di vedere come funziona. Grazie. –

6

Io corro in questo problema così

il problema sta nel fatto che il metodo GetUser() senza parametri è implementato come un metodo statico della classe.

Considerando che Membership.Provider (quando deriso) non contiene un metodo GetUser() senza parametri.

A proposito, ecco come ho risolto questo problema. Ho incapsulato la chiamata statica nella mia classe che implementa un'interfaccia in modo che possa essere derisa.

public interface IStaticMembershipService 
{ 
    MembershipUser GetUser(); 

    void UpdateUser(MembershipUser user); 
} 

public class StaticMembershipService : IStaticMembershipService 
{ 
    public System.Web.Security.MembershipUser GetUser() 
    { 
     return Membership.GetUser(); 
    } 

    public void UpdateUser(MembershipUser user) 
    { 
     Membership.UpdateUser(user); 
    }  
} 
1

In ASP.NET MVC hanno risolto questo incapsulando (avvolgimento) la funzionalità appartenenza in un MebershipService. Quale (ad esempio: attraverso l'iniezione) puoi facilmente prendere in giro i tuoi test.

Un esempio di servizi di simulazione ... http://www.asp.net/learn/mvc/tutorial-30-cs.aspx tuttavia non usano l'iniezione.

Un bell'esempio è in realtà il progetto di test generato quando si crea un'applicazione ASP.NET. Nel seguente codice è possibile vedere come prendere in giro il FormsAuthentication e l'appartenenza degli oggetti:

[TestMethod] 
    public void ConstructorSetsProperties() 
    { 
     // Arrange 
     IFormsAuthentication formsAuth = new MockFormsAuthenticationService(); 
     IMembershipService membershipService = new AccountMembershipService(); 

     // Act 
     AccountController controller = new AccountController(formsAuth, membershipService); 

     // Assert 
     Assert.AreEqual(formsAuth, controller.FormsAuth, "FormsAuth property did not match."); 
     Assert.AreEqual(membershipService, controller.MembershipService, "MembershipService property did not match."); 
    }