用于mvc登录的NUnit测试用例

1 asp.net asp.net-mvc nunit

我们可以为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);
 }
Run Code Online (Sandbox Code Playgroud)

mil*_*uak 5

1)当模型有效时,您可以验证是否使用正确的参数调用WebSecurity.Login

2)您可以验证WebSecurity.Login何时返回true,您将被重定向到reutnrUrl

3)如果model无效,您可以验证ModelState是否包含您的错误并返回ViewResult.

你将不得不重构对WebSecurity的调用,你将不得不嘲笑它.可能必须使用依赖注入技术.

1)您必须在界面后隐藏WebSecurity并仅通过该界面使用它(我假设您的WebSecurity静态类来自WebMatrix.WebData命名空间).

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);
     }
}
Run Code Online (Sandbox Code Playgroud)

2)在您的控制器中,您必须创建一个WebSecurityHelper实例,通常使用IoC框架(如StructureMap)在此处输入链接描述.但是对于这个例子,我将在控制器构造函数中初始化WebSecurityHelper,这仍然允许我注入mock进行测试.

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);
   }      
}
Run Code Online (Sandbox Code Playgroud)

3)在你的单元测试中,你必须模拟IWebSecurityHelper.有许多模拟框架,我个人更喜欢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));
   }

}
Run Code Online (Sandbox Code Playgroud)