views:

525

answers:

4
+6  Q: 

Mocking Membership

I'm writing a custom Profile provider, but I still intend to use the default AspNetSqlMembershipProvider as my Membership provider. My GetAllProfiles() method in my Profile provider looks like this:

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   }

How do I mock the Membership.GetUser() call so that I can write tests for this method? Any suggestions or examples? Thanks.

+1  A: 

Could you inject a MembershipProvider instance into your profile provider and, if none is injected, fall back on using Membership.Provider?

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

Your profile provider would interact with the membership provider through the value returned by this property. In your test you'd inject the fake/mock MembershipProvider instance.

If you instead want to just mock the static methods on Membership, you'll have to use something like TypeMock, I guess.

Dave Cluderay
Yeah, I was thinking about using TypeMock or Moq, but I haven't seen any examples for this particular scenario. I'll play around with an injection as you suggested to see how that works. Thanks.
Rob Abernethy
+2  A: 

I'm running into this problem as well

the problem lies in the fact that the method GetUser() without parameters is implemented as a static method on the class.

Whereas the Membership.Provider (when mocked) does not contain a GetUser() method without parameters.

By the way here is how I fixed this problem. I encapsulated the static call in my own class which implements an interface so it can be mocked.

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);
 }  
}
sjors miltenburg
+1  A: 

In ASP.NET MVC they solved this by encapsulating (wrapping) the membership fucntionality in a MebershipService. Which (for instance: through injection) you can then easily mock in your tests.

An example of mocking services... http://www.asp.net/learn/mvc/tutorial-30-cs.aspx they don't use injection though.

A nice example is actually the test project generated when you create an ASP.NET application. In the following code you can see how they mock The FormsAuthentication and Membership objects:

    [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.");
    }
Cohen
A: 

can you please share the sample code how you mocked the membership.getuser it will be great help..

prakash