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

发布于 2024-12-07 14:02:43 字数 3058 浏览 0 评论 0原文

我想为以下控制器创建单元测试,但在 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);
        }
    }

单元测试代码:

    [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");

        }
    }

当我用 google 搜索时,我得到了以下代码,但我不知道如何将成员身份传递给 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);

请帮助我使该代码正常工作。

I want to create a Unit test for the following controller but it got fail in the Membership class:


    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


    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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

欢你一世 2024-12-14 14:02:43

看起来好像您正在使用 IMembershipServive 和 IFormsAuthenticationService 的具体实例,因为您正在使用访问器来初始化它们。当您使用具体类时,您并没有真正单独测试该类,这解释了您所看到的问题。

您真正想做的是测试控制器的逻辑,而不是其他服务的功能。

幸运的是,这是一个简单的修复,因为 MembershipService 和 FormsService 是控制器的公共成员,可以用模拟实现替换。

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

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

现在您可以为您的控制器测试几个场景:

  • 当 MembershipService 找不到用户时会发生什么?
  • 密码无效?
  • 用户名和密码是否有效?

请注意,如果您的 AuthenticationServicePack 有其他服务或依赖项,它也会导致问题。您可能需要考虑将其移至控制器的属性,或者如果每次身份验证需要一个实例,请考虑使用工厂或其他服务来封装此逻辑。

It appears as though you are using concrete instances of the IMembershipServive and IFormsAuthenticationService because you are using the Accessor to initialize them. 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.

// 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?
  • 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. 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文