如何在MVC中编写包含FormsAuthenticationTicket的单元测试用例

时间:2013-11-30 14:10:19

标签: c# asp.net-mvc unit-testing

在以下方法中,我正在解密cookie以使用其中的UserName返回它。 我尝试为它编写测试用例,但返回的cookie为null,因为它没有登录。 任何人都可以帮我写一个测试用例吗?

public string Username()
        {
            LoggingManager.Debug("Entering Username - UserManager");
            var authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName.ToString(CultureInfo.InvariantCulture)];
            if (authCookie != null)
            {
                FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
                if (authTicket != null) return authTicket.Name;
            }
            const string anonymys = "xyz";
            LoggingManager.Debug("Exiting Username - UserManager");
            return anonymys;
        }

1 个答案:

答案 0 :(得分:3)

你正在碰到单元测试现在使用静态类的东西的乐趣。您有两种选择:

  1. 在实现接口的类中包含您想要从HttpContext中获取的功能,然后将模拟注入类中以进行单元测试。

  2. 使用Fakes framework之类的内容创建一个垫片,暂时为单元测试创​​建假HttpContext

  3. 方法#1的例子:

    public interface ICookieProvider
    {
        HttpCookieCollection GetCookies();
    }
    
    public class RealCookieProvider : ICookieProvider
    {
        public HttpCookieCollection GetCookies() 
        {
            return HttpContext.Current.Request.Cookies;
        }
    }
    

    然后,通过构造函数将cookie提供程序注入控制器:

    private ICookieProvider cookieProvider;
    public MyController(ICookieProvider cookieProvider)
    {
        this.cookieProvider = cookieProvider;
    }
    public MyController() : this(new RealCookieProvider()) { }
    

    然后,您可以使用模拟框架创建一个ICookieProvider,返回您想要的任何内容。

    请注意,我几乎在所有情况下都更喜欢方法#1。方法#2只隐藏了这个问题,即你编写了紧密耦合,难以测试的代码。方法#1通过引入松耦合解决了这个问题。