Question

What kind of test cases can we write for the following login controller in asp.net mvc

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
 if (ModelState.IsValid && WebSecurity.Login(model.UserName, model.PasswordpersistCookie: model.RememberMe))
 {
    return RedirectToLocal(returnUrl);
 }
 ModelState.AddModelError("", "The user name or password provided is incorrect.");
 return View(model);
 }
Était-ce utile?

La solution

1) You can verify that WebSecurity.Login is called with correct parameters when model is valid

2) You can verify when WebSecurity.Login returns true you get redirected to the reutnrUrl

3) if model is not valid you can verify that ModelState contains your error and returned ViewResult.

You will have to refactor call to the WebSecurity though, you will have to mock it. Probably will have to use dependency injection technique.

Example

1) You will have to hide your WebSecurity behind an interface and use it only through that interface (I assume your WebSecurity static class comes from WebMatrix.WebData namespace).

public interface IWebSecurityHelper
{
   bool Login(string userName, string password, bool isPersistent = false)
}

// Implementation of your web security helper

using WebMatrix.WebData;

public class WebSecurityHelper : IWebSecurityHelper
{
     public bool Login(string userName, string password, bool isPersistent = false)
     {
        WebSecurity.Login(userName, password, isPersistent);
     }
}

2) In your controller you will have to have create an instance of WebSecurityHelper, usually it is done using IoC frameworks suchs StructureMap or enter link description here. But for this example I will just initialize the WebSecurityHelper in the controllers constructor, which will still allow me to inject mock for testing.

public class LoginController
{
   private readonly IWebSecurityHelper _helper;

   public LoginController(IWebSecurityHelper helper)
   {
     _helper = helper;
   }

   // passing your implementation of the WebSecurityHelper 
   public LoginController() : this(new WebSecurityHelper()) {}

   [HttpPost]
   [AllowAnonymous]
   [ValidateAntiForgeryToken]
   public ActionResult Login(LoginModel model, string returnUrl)
   {
       if (ModelState.IsValid && _helper.Login(model.UserName,model.PasswordpersistCookie: model.RememberMe))
       {
         return RedirectToLocal(returnUrl);
       }

       ModelState.AddModelError("", "The user name or password provided is incorrect.");

       return View(model);
   }      
}

3) In your unit test, you will have to mock IWebSecurityHelper. There are many mocking frameworks, I personally prefer Moq.

[TestFixture]
public class LoginControllerTests
{
   // this test will verify that your controller called Login method of the  WebSecurityHelper successfully with correct parameters
   [Test]
   public void LoginAction_Must_Call_WebSecurityLogin()
   { 
       var loginModel = new LoginModel() { UserName = "test", Password = "test" }

       var helperMock = new Mock<IWebSecurityHelper>();
       helperMock.Expect(m => m.Login(loginModel.UserName, loginModel.Password));
       var controller = new LoginController(_helperMock.Object);
       controller.Login(loginModel, string.Empty);
       helperMock.Verify(m => m.Login(loginModel.UserName, loginModel.Password));
   }

}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top