如何在使用Membership时测试ASP.NET MVC 3身份验证

Rad*_*u D 8 c# asp.net asp.net-mvc unit-testing

我想测试我的AccountController.问题是在Register方法中我使用下一行来创建用户:

Membership.CreateUser(model.Email, model.Password, model.Email, null, null, true, null, out createStatus);
Run Code Online (Sandbox Code Playgroud)

在Web应用程序中,我使用了CustomMembershipProvider我使用web.config设置的内容.在我的单元测试中的会员级标准SqlMembershipProvider.而不是我CustomMembershipProvider在我的应用程序中使用的那些.

如何在单元测试环境中设置成员资格?我的意思是以编程方式设置它,因为asp net在读取web.config文件后设置它.

我已经使用接口来模拟用户管理数据层,但我在想是否有办法在这种情况下避免接口.能够在单元测试中设置成员资格的模拟实现.

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();
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*kes 8

定义成员资格界面,如下所示:

public interface IMembershipProvider
{
    void CreateUser(string username, string password);
}
Run Code Online (Sandbox Code Playgroud)

...为你的MVC应用程序实现它,如下所示:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

...然后将其注入您的控制器并像这样使用它:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

ASP.NET使用静态类,例如Membership许多东西,但静态类访问总是使单元测试变得困难.标准解决方案是为服务定义接口,使用静态ASP.NET类实现它,并将其注入控制器.

您可以使用默认DependencyResolverUnity等容器来设置注入(如果您还没有).