如何单元测试会话状态

时间:2010-09-17 23:39:57

标签: asp.net-mvc unit-testing rhino-mocks session-state

我正在试图弄清楚如何对我的对象进行单元测试,使其自身保持会话状态。

控制器执行类似......

的操作
    [HttpPost]
    public ActionResult Update(Account a)
    {
        SessionManager sm = SessionManager.FromSessionState(HttpContext.Current.Session);
        if ( a.equals(sm.Account) )
          sm.Account = a;
        return View("View", a);
    }

会话管理器将自身序列化为会话状态

public class SessionManager
    {
        public static SessionManager FromSessionState(HttpSessionStateBase state)
        {
            return state["sessionmanager"] as SessionManager ?? new SessionManager();
        }

        public Guid Id { get; set; }
        public Account Account { get; set; }
        public BusinessAssociate BusinessAssociate {get; set; }
    }

我认为单元测试有两种方法......

  1. 在静态实例化器中传递会话状态引用,然后从中恢复。这将允许我模拟这个参数,一切都会很好。

    public static SessionManager FromSessionState(HttpSessionStateWrapper session) {   返回会话[“sessionmanager”]作为SessionManager ??新的SessionManager(); }

  2. 为SessionManager创建一个模拟器并将其用于测试控制器。

2 个答案:

答案 0 :(得分:2)

这是一个想法:创建会话管理器“持久性”接口:

public interface ISessionManagerPersist
{
    SessionManager Load();
    void Save(SessionManager sessionManager);
}

创建基于HTTPSession的持久性实现:

public class SessionStatePersist : ISessionManagerPersist
{
    public SessionManager Load()
    {
        return HttpContext.Current.Session["sessionmanager"] as SessionManager ?? new SessionManager();
    }

    public void Save(SessionManager sessionManager)
    {
        HttpContext.Current.Session["sessionmanager"] = sessionManager;
    }
}

现在让你的控制器依赖ISessionManagerPersist。您可以在测试期间注入存根ISessionManagerPersist,并在生产期间使用基于会话的存根。如果你决定坚持其他地方(比如数据库或其他东西),这也有不需要改变的好处。只需实施新的ISessionManagerPersist

答案 1 :(得分:1)

目前,此控制器操作非常难以进行单元测试,因为它调用的是依赖HttpContext.Current的静态方法。虽然第一种方法似乎在第二种方法中起作用,但您仍需要在某处传递会话状态,以便管理员可以使用它。也不要通过HttpSessionStateWrapper,而是使用HttpSessionStateBase