测试帐户/登录操作

dav*_*988 0 asp.net-mvc unit-testing controllercontext formsauthentication

我正在使用Visual Studio 2010的内置测试工具和本文中的类库来测试Account/Loggon操作,以创建虚假的控制器上下文.当我运行测试方法时,这段代码行:

  FormsAuthentication.SetAuthCookie(username, false);    
Run Code Online (Sandbox Code Playgroud)

抛出异常:对象引用未设置为对象的实例

为了测试loggon动作,我想我应该创建一个带有伪控制器上下文的控制器,它具有cookie集合.这是我的测试代码块:

   AccountController controller = new AccountController();
   var cookies = new HttpCookieCollection();

   controller.ControllerContext = new FakeControllerContext(controller, cookies);

   ActionResult result = controller.RemoteLogOn(username, password);
Run Code Online (Sandbox Code Playgroud)

RPM*_*984 9

我不确定这是不是正确的方法,但这就是我们所做的,而且它有效.

而不是直接使用FormsAuthentication.SetAuthCookie,将其抽象到接口中,例如IFormsAuthenticationService,按照常规实现.

在需要的MVC控制器中接受,例如:

public AccountController(IFormsAuthenticationService formsAuthenticationService)
{
   _formsAuthenticationService = formsAuthenticationService; // should use DI here
}

public ActionResult LogOn(string username, string pw)
{
   if (yourLogicWhichChecksPw)
       _formsAuthenticationService.SetAuthCookie(username, false);
   return RedirectToAction("Index");
}
Run Code Online (Sandbox Code Playgroud)

然后在你的单元测试中,使用像Moq这样的东西来伪造界面.

var username = "blah";
var pw = "blah";
var fakesFormsAuth = new Mock<IFormsAuthenticationService>();
fakeFormsAuth.Verify(x => x.SetAuthCookie(username, false), Times.AtLeastOnce());                 
var controller = new AccountController(fakedFormsAuth.Object);
controller.LogOn(username, pw);
Run Code Online (Sandbox Code Playgroud)

模仿这个的原因是因为绝对不需要对表单身份验证进行单元测试.它是ASP.NET框架的内置,经过良好测试和稳定的部分.这就是为什么我们在不关心底层实现的情况下模拟的东西,而是我们只测试满足某些条件(它被调用,抛出异常,设置了一些变量等).

测试你自己的代码,而不是.NET的机制.

至于斯蒂芬·沃尔特(Stephen Walther)的文章,当你的测试中的某些代码需要请求中的数据时,更多的是伪造RequestContext.例如User.Identity,Request.IsAuthenticated,Form变量等.这就是你需要伪造上下文的地方,例如以下代码:

public ActionResult Save(SomeModel)
{
   var user = Request.User.Identity; // this will be null, unless you fake the context.
}
Run Code Online (Sandbox Code Playgroud)

  • 自从我昨天开始寻找如何模拟SetAuthCookie以来,这是我最接近的事情.谢谢你. (2认同)