如何对使用FormsAuthentication的ASP.NET MVC控制器进行单元测试?

47

我正在以测试驱动的方式使用ASP.NET MVC解决方案,并希望使用表单认证登录用户到我的应用程序中。我想在控制器中最终得到的代码类似于:

FormsAuthentication.SetAuthCookie(userName, false);
我的问题是如何编写一个测试来验证这段代码?有没有方法可以检查SetAuthCookie方法是否使用了正确的参数?是否有任何方法可以注入虚假/模拟FormsAuthentication?
1个回答

68

我会先编写一个接口和包装类来封装这个逻辑,然后在我的控制器中使用该接口:

public interface IAuth 
{
    void DoAuth(string userName, bool remember);
}

public class FormsAuthWrapper : IAuth 
{
    public void DoAuth(string userName, bool remember) 
    {
        FormsAuthentication.SetAuthCookie(userName, remember);
    }
}

public class MyController : Controller 
{
    private readonly IAuth _auth;

    public MyController(IAuth auth) 
    {
        _auth = auth;
    }

}

现在,IAuth 可以在单元测试中轻松地模拟,并验证控制器是否调用了预期的方法。我不会对 FormsAuthWrapper 类进行单元测试,因为它只是将调用委托给 FormsAuthentication,后者执行了它应该执行的操作(得到了微软的保证 :-))。


2
在这个问题上我赞同,不要测试其他人的框架,只需测试你自己使用它们的情况。我们在我们的应用程序中也做同样的事情(包装FormsAuth等)。 - chadmyers
18
叹气 微软对这个框架的可测试性非常自豪!我希望有一些内置的方法可以模拟它而不需要包装。看来没有 :( - maz
6
问题不在于框架不能进行测试...问题在于FormsAuthentication类早于MVC的单元测试设计。正如Darin所提到的,解决这个问题的最佳方法是使用接口将控制器与具有静态方法的类解耦。 - Jesse
你能举个例子来展示如何模拟 IAuth Darin 吗? - DevDave
1
@Tyler,你应该让你的AccountController在构造函数中使用IAuth接口,不再使用任何FormsAuthentication。 - Darin Dimitrov
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接