Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 711
Rob Abernethy Avatar asked Jun 08 '09 20:06

Rob Abernethy


3 Answers

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);
    }       
}
like image 78
Sjors Miltenburg Avatar answered Jan 01 '23 19:01

Sjors Miltenburg


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.

like image 44
Dave Cluderay Avatar answered Jan 01 '23 18:01

Dave Cluderay


In ASP.NET MVC they solved this by encapsulating (wrapping) the membership functionality 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.");
    }
like image 42
Cohen Avatar answered Jan 01 '23 19:01

Cohen