views:

214

answers:

1

Trying to figure out how to adequately test my accounts controller. I am having problem testing the successful logon scenario.

Issue 1) Am I missing any other tests.(I am testing the model validation attributes separately)

Issue 2) Put_ReturnsOverviewRedirectToRouteResultIfLogonSuccessAndNoReturnUrlGiven() and Put_ReturnsRedirectResultIfLogonSuccessAndReturnUrlGiven() test are not passing. I have narrowed it down to the line where i am calling _membership.validateuser(). Even though during my mock setup of the service i am stating that i want to return true whenever validateuser is called, the method call returns false.

Here is what I have gotten so far

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  A: 

Figured out how to fix my tests.

        [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"]);
        }
Anil Ali