Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test ASP.NET MVC 3 authentication when using Membership

I want to test my AccountController. The problem is that in Register method I use the next line to create the user:

Membership.CreateUser(model.Email, model.Password, model.Email, null, null, true, null, out createStatus);

In the web application I use a CustomMembershipProvider which I set using web.config. In my unit test Membership class in standard SqlMembershipProvider. And not my CustomMembershipProvider that I use in my app.

How can I set up membership in unit test context? I mean to set it up programatically as asp net set it after reading web.config file.

I already use interface for mocking users management data layer but I was thinking if there is a way to avoid interface in this case. To be able to set up a mock implementation of membership in unit test.

public void RegisterTest()
{
    IUsersManager repository = new Tests.Data.UsersManager();
    AccountController target = new AccountController(repository); 
    //be able to set Membership underlying provider
    Membership.Provider = new MockMembershipProvider();
}
like image 901
Radu D Avatar asked Feb 05 '12 19:02

Radu D


People also ask

How Windows authentication works in ASP.NET MVC?

When you enable Windows authentication, your web server becomes responsible for authenticating users. Typically, there are two different types of web servers that you use when creating and deploying an ASP.NET MVC application.

How authentication and authorization works in ASP.NET MVC?

Windows Authentication is used in conjunction with IIS authentication. The Authentication is performed by IIS in one of three ways such as basic, digest, or Integrated Windows Authentication. When IIS authentication is completed, then ASP.NET uses the authenticated identity to authorize access.

What is the default authentication in MVC?

The default authentication is, Individual User Accounts.


2 Answers

Define a membership interface, something like this:

public interface IMembershipProvider
{
    void CreateUser(string username, string password);
}

...implement it for your MVC application like this:

public class AspDotNetMembershipProvider : IMembershipProvider
{
    public void CreateUser(string username, string password)
    {
        string createStatus;

        Membership.CreateUser(
            username,
            password,
            username,
            null,
            null,
            true,
            null,
            out createStatus);

        // throw an exception if createStatus isn't as expected
    }
}

...then inject it into your controller and use it like this:

public class AccountController
{
    private readonly IMembershipProvider _membershipProvider;

    public AccountController(IMembershipProvider membershipProvider)
    {
        this._membershipProvider = membershipProvider;
    }

    public ActionResult Register(RegistrationModel model)
    {
        // Try and catch this, returning a success ActionResult if it worked:
        this._membershipProvider.CreateUser(model.Email, model.Password);
    }
}

ASP.NET uses static classes like Membership for a number of things, but static class access always makes unit testing difficult. The standard solution is to define an interface for the service, implement it using the static ASP.NET class, and inject it into your controllers.

You can set up the injection (if you've not already) by using a default DependencyResolver and a DI container like Unity.

like image 195
Steve Wilkes Avatar answered Oct 21 '22 19:10

Steve Wilkes


I've created a more structured membership provider which have been breaken down into three different interfaces (and the provider is resolving them using DependencyResolver).

It makes it easy to unit test the provider. Just test your implementation of the IAccountRepository.

You can read about it here: http://blog.gauffin.org/2011/09/a-more-structured-membershipprovider/

or just install the nuget package:

install-package griffin.mvccontrib
like image 29
jgauffin Avatar answered Oct 21 '22 20:10

jgauffin