如何为表单身份验证的帐户控制器编写测试

时间:2010-04-03 18:51:05

标签: asp.net-mvc unit-testing asp.net-membership rhino-mocks xunit.net

试图找出如何充分测试我的帐户控制器。我在测试成功的登录方案时遇到问题。

问题1)我错过了任何其他测试。(我正在分别测试模型验证属性)

问题2)Put_ReturnsOverviewRedirectToRouteResultIfLogonSuccessAndNoReturnUrlGiven()和Put_ReturnsRedirectResultIfLogonSuccessAndReturnUrlGiven()测试未通过。我把它缩小到我调用_membership.validateuser()的行。即使在我的服务的模拟设置期间,我声明我想在调用validateuser时返回true,方法调用返回false。

这是我到目前为止所得到的

AccountController.cs

[HandleError]
public class AccountController : Controller
{
    private IMembershipService _membershipService;

    public AccountController()
        : this(null)
    {
    }

    public AccountController(IMembershipService membershipService)
    {
        _membershipService = membershipService ?? new AccountMembershipService();
    }

    [HttpGet]
    public ActionResult LogOn()
    {
        return View();
    }

    [HttpPost]
    public ActionResult LogOn(LogOnModel model, string returnUrl)
    {
        if (ModelState.IsValid)
        {
            if (_membershipService.ValidateUser(model.UserName,model.Password))
            {
                if (!String.IsNullOrEmpty(returnUrl))
                {
                    return Redirect(returnUrl);
                }
                return RedirectToAction("Index", "Overview");
            }
            ModelState.AddModelError("*", "The user name or password provided is incorrect.");
        }

        return View(model);
    }

}

AccountServices.cs

public interface IMembershipService
{
    bool ValidateUser(string userName, string password);
}

public class AccountMembershipService : IMembershipService
{
    public bool ValidateUser(string userName, string password)
    {
        throw new System.NotImplementedException();
    }
}

AccountControllerFacts.cs

public class AccountControllerFacts
{
    public static AccountController GetAccountControllerForLogonSuccess()
    {
        var membershipServiceStub = MockRepository.GenerateStub<IMembershipService>();
        var controller = new AccountController(membershipServiceStub);
        membershipServiceStub
               .Stub(x => x.ValidateUser("someuser", "somepass"))
               .Return(true);
        return controller;
    }

    public static AccountController GetAccountControllerForLogonFailure()
    {
        var membershipServiceStub = MockRepository.GenerateStub<IMembershipService>();
        var controller = new AccountController(membershipServiceStub);
        membershipServiceStub
               .Stub(x => x.ValidateUser("someuser", "somepass"))
               .Return(false);
        return controller;
    }

    public class LogOn
    {
        [Fact]
        public void Get_ReturnsViewResultWithDefaultViewName()
        {
            // Arrange
            var controller = GetAccountControllerForLogonSuccess();

            // Act
            var result = controller.LogOn();

            // Assert
            Assert.IsType<ViewResult>(result);
            Assert.Empty(((ViewResult)result).ViewName);
        }

        [Fact]
        public void Put_ReturnsOverviewRedirectToRouteResultIfLogonSuccessAndNoReturnUrlGiven()
        {
            // Arrange
            var controller = GetAccountControllerForLogonSuccess();
            var user = new LogOnModel();

            // Act
            var result = controller.LogOn(user, null);
            var redirectresult = (RedirectToRouteResult) result;

            // Assert
            Assert.IsType<RedirectToRouteResult>(result);
            Assert.Equal("Overview", redirectresult.RouteValues["controller"]);
            Assert.Equal("Index", redirectresult.RouteValues["action"]);
        }

        [Fact]
        public void Put_ReturnsRedirectResultIfLogonSuccessAndReturnUrlGiven()
        {
            // Arrange
            var controller = GetAccountControllerForLogonSuccess();
            var user = new LogOnModel();

            // Act
            var result = controller.LogOn(user, "someurl");
            var redirectResult = (RedirectResult) result;

            // Assert
            Assert.IsType<RedirectResult>(result);
            Assert.Equal("someurl", redirectResult.Url);
        }

        [Fact]
        public void Put_ReturnsViewIfInvalidModelState()
        {
            // Arrange
            var controller = GetAccountControllerForLogonFailure();
            var user = new LogOnModel();
            controller.ModelState.AddModelError("*","Invalid model state.");

            // Act
            var result = controller.LogOn(user, "someurl");
            var viewResult = (ViewResult) result;

            // Assert
            Assert.IsType<ViewResult>(result);
            Assert.Empty(viewResult.ViewName);
            Assert.Same(user,viewResult.ViewData.Model);
        }

        [Fact]
        public void Put_ReturnsViewIfLogonFailed()
        {
            // Arrange

            var controller = GetAccountControllerForLogonFailure();
            var user = new LogOnModel();

            // Act
            var result = controller.LogOn(user, "someurl");
            var viewResult = (ViewResult) result;

            // Assert
            Assert.IsType<ViewResult>(result);
            Assert.Empty(viewResult.ViewName);
            Assert.Same(user,viewResult.ViewData.Model);
            Assert.Equal(false,viewResult.ViewData.ModelState.IsValid);
        }
    }
}

1 个答案:

答案 0 :(得分:2)

弄清楚如何修复我的测试。

        [Fact]
        public void Put_ReturnsRedirectToRouteResultForOverviewIfLogonSuccessAndNoReturnUrlGiven()
        {
            // Arrange
            var mocks = new MockRepository();
            var mockMembershipService = mocks.StrictMock<IMembershipService>();
            using (mocks.Record())
            {
                Expect.Call(mockMembershipService.ValidateUser("", "")).IgnoreArguments().Return(true).Repeat.Any();
            }
            var controller = new AccountController(mockMembershipService);
            var user = new LogOnModel();

            // Act
            ActionResult result;
            using (mocks.Playback()){
                result = controller.LogOn(user, null);
            }

        // Assert
            Assert.IsType<RedirectToRouteResult>(result);
            var redirectresult = (RedirectToRouteResult)result;
            Assert.Equal("Overview", redirectresult.RouteValues["controller"]);
            Assert.Equal("Index", redirectresult.RouteValues["action"]);
        }