【问题标题】:How to mock membership provider如何模拟会员提供者
【发布时间】:2015-01-18 13:38:43
【问题描述】:

如何模拟我的会员资格提供程序(我有自定义会员资格提供程序,但不知道如何模拟它并将会员资格作为提供程序提供,因为 Membership.Provider 只有吸气剂)并在我的单位中使用该模拟的自定义会员资格提供程序测试?

这是我的控制器

public class MyController
 {   
        private IMyRepository myRepository;

        public MyController(IMyRepository myRepository) 
        {
            this.myRepository= myRepository;
        }    

       [HttpGet]
        public ActionResult Create()
        {
            var user = Membership.GetUser(); // <--- I want mock this method
            ViewBag.User = user;
            return View("Create");
        }
}

这是我的测试(使用起订量)

 [TestClass]
    public class MyControllerUnitTest
    {
        private MyController controller;

        public MyControllerUnitTest()
        {
            Mock<IMyRepository > myRepository = new Mock<IMyRepository>();
            var controller = new GroupController(myRepository.Object);
        }

        [TestMethod]
        public void TestMethod1()
        {
            var result = controller.Create() as ViewResult;
            Assert.AreEqual("Create", result.ViewName);
        }
    }

【问题讨论】:

  • 我已经添加了一个答案,看看是否有帮助。

标签: c# asp.net-mvc unit-testing moq membership-provider


【解决方案1】:

@Sergey 是对的,你不应该直接使用Membership 类。我知道在某些情况下您需要使用 Membership 类,因此添加以下信息。

您需要将Membership 类包装在一个类中(从接口派生),然后您可以在任何需要的地方进行模拟。

我们得到的内容的简短版本:

public interface IMembershipService
{
    MembershipUser GetUserDetails(string emailAddress);
    void CreateUserRole(string roleName);
    void AssignUserToRole(string username, string roleName);
    bool ValidateUserCredentials(string username, string password);
    void SetAuthenticationCookie(string username, bool rememberMe);
    void SignOut();
    void UpdateUser(MembershipUser membershipUser);
    bool DeleteUser(string username);
}

    public class MembershipService : IMembershipService
    {
        public MembershipUser GetUserDetails(string emailAddress)
        {
            return Membership.GetUser(emailAddress);
        }

        public MembershipUser GetUserDetails(Guid membershipId)
        {
            return Membership.GetUser(membershipId);
        }
   }

在你的控制器中注入它:

public class AdminController : Controller
{
    private readonly IMembershipService _membershipService;
    private readonly IEmailService _emailService;

    public AdminController(IMembershipService membershipService, 
        IEmailService emailService)
    {
        _membershipService = membershipService;
        _emailService = emailService;
    }
}

在单元测试中你可以这样做:

    var membershipService = new Mock<IMembershipService>();

【讨论】:

    【解决方案2】:

    首先你应该从System.Web.Mvc.Controller类继承MyController

    public class MyController : System.Web.Mvc.Controller
    

    那么你应该避免使用Membership。它是静态的,并非设计为可单元测试的。更好的选择是使用控制器的User 属性:

    [HttpGet]
    public ActionResult Index()
    {
      ViewBag.UserName = this.User.Identity.Name;
      return View("Index");
    }
    

    controller.User 属性可以使用ControllerContext 模拟:

      // arrange
      Mock<HttpContextBase> httpContext = new Mock<HttpContextBase>();
      httpContext.SetupGet(c => c.User.Identity.Name).Returns("John Doe");
    
      Mock<ControllerBase> baseControler = new Mock<ControllerBase>();
    
      this.controller.ControllerContext =
        new ControllerContext(httpContext.Object, new RouteData(), baseControler.Object);
    
      // act
      var result = this.controller.Index();
    
      // assert
      Assert.AreEqual("John Doe", ((ViewResult)result).ViewBag.UserName);
    

    【讨论】:

      猜你喜欢
      • 2010-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-26
      • 2011-04-26
      相关资源
      最近更新 更多