我不确定这是否是正确的方法,但这是我们所做的,并且有效。
与其直接使用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");
}
然后在您的单元测试中,使用诸如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);
嘲笑这一点的原因是因为绝对不需要对表单身份验证进行单元测试。它是 ASP.NET 框架的内置、经过良好测试且稳定的部分。这就是为什么我们在不关心底层实现的地方模拟事情,而是只测试满足某些条件(它被调用、抛出异常、设置了一些变量等)。
测试您自己的代码,而不是 .NET 的机制。
至于 Stephen Walther 的文章,当您的测试的某些代码需要 Request 中的数据时,这更多是为了伪造 RequestContext。比如User.Identity、Request.IsAuthenticated、Form变量等。这就是你需要伪造上下文的地方,比如下面的代码:
public ActionResult Save(SomeModel)
{
var user = Request.User.Identity; // this will be null, unless you fake the context.
}