简体   繁体   English

单元测试控制器-成员资格错误

[英]Unit test controller - membership error

I want to create a Unit test for the following controller but it got fail in the Membership class: 我想为以下控制器创建单元测试,但是在Membership类中失败:

public class AccountController:BaseController
    {
        public IFormsAuthenticationService FormsService { get; set; }
        public IMembershipService MembershipService { get; set; }

        protected override void Initialize(RequestContext requestContext)
        {
            if(FormsService == null) { FormsService = new FormsAuthenticationService(); }
            if(MembershipService == null) { MembershipService = new AccountMembershipService(); }

            base.Initialize(requestContext);
        }
        public ActionResult LogOn()
        {
            return View("LogOn");
        }

        [HttpPost]
        public ActionResult LogOnFromUser(LappLogonModel model, string returnUrl)
        {
            if(ModelState.IsValid)
            {
                string UserName = Membership.GetUserNameByEmail(model.Email);
                if(MembershipService.ValidateUser(model.Email, model.Password))
                {
                    FormsService.SignIn(UserName, true);

                    var service = new AuthenticateServicePack();
                    service.Authenticate(model.Email, model.Password);
                    return RedirectToAction("Home");
                }
            }
            ModelState.AddModelError("", "The user name or password provided is incorrect.");
            return View("LogOn", model);
        }
    }

Unit test code: 单元测试代码:

[TestClass]
    public class AccountControllerTest
    {
        [TestMethod]
        public void LogOnPostTest()
        {
            var mockRequest = MockRepository.GenerateMock();
            var target = new AccountController_Accessor();
            target.Initialize(mockRequest);
            var model = new LogonModel() { UserName = "test", Password = "1234" };
            string returnUrl = string.Empty;
            ActionResult expected = null;
            ActionResult actual = target.LogOn(model, returnUrl);
            if (actual == null)
                Assert.Fail("should have redirected");

        }
    }

When I googled, I got the following code but I don't know how to pass the membership to the accountcontroller 当我用谷歌搜索时,我得到了以下代码,但是我不知道如何将成员身份传递给accountcontroller

var httpContext = MockRepository.GenerateMock();
                var httpRequest = MockRepository.GenerateMock();
                httpContext.Stub(x => x.Request).Return(httpRequest);
                httpRequest.Stub(x => x.HttpMethod).Return("POST");

                //create a mock MembershipProvider & set expectation
                var membershipProvider = MockRepository.GenerateMock();
                membershipProvider.Expect(x => x.ValidateUser(username, password)).Return(false);

                //create a stub IFormsAuthentication
                var formsAuth = MockRepository.GenerateStub();

            /*But what to do here???{...............
                ........................................
                ........................................}*/

                controller.LogOnFromUser(model, returnUrl);

Please help me to get this code working. 请帮助我使此代码正常工作。

It appears as though you are using concrete instances of the IMembershipServive and IFormsAuthenticationService because you are using the Accessor to initialize them. 似乎您正在使用IMembershipServive和IFormsAuthenticationService的具体实例,因为您正在使用访问器对其进行初始化。 When you use concrete classes you are not really testing this class in isolation, which explains the problems you are seeing. 当您使用具体的类时,您并不是真正地在单独测试该类,这可以解释您所遇到的问题。

What you really want to do is test the logic of the controller, not the functionalities of the other services. 您真正想做的是测试控制器的逻辑,而不是其他服务的功能。

Fortunately, it's an easy fix because the MembershipService and FormsService are public members of the controller and can be replaced with mock implementations. 幸运的是,这很容易解决,因为MembershipService和FormsService是控制器的公共成员,可以用模拟实现替换。

// moq syntax:
var membershipMock = new Mock<IMembershipService>();
var formsMock = new Mock<IFormsAuthenticationService>();

target.FormsService = formsMock.Object;
target.MembershipService = membershipService.Object;

Now you can test several scenarios for your controller: 现在,您可以为控制器测试几种方案:

  • What happens when the MembershipService doesn't find the user? 如果MembershipService找不到用户怎么办?
  • The password is invalid? 密码无效?
  • The user and password is is valid? 用户名和密码是否有效?

Note that your AuthenticationServicePack is also going to cause problems if it has additional services or dependencies. 请注意,如果AuthenticationServicePack具有其他服务或依赖项,也会引起问题。 You might want to consider moving that to a property of the controller or if it needs to be a single instance per authentication, consider using a factory or other service to encapsuate this logic. 您可能需要考虑将其移至控制器的属性,或者如果每次身份验证需要将其作为单个实例,则可以考虑使用工厂或其他服务来封装此逻辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM