2010-09-17 65 views
1

我想弄清楚如何单元测试我自己持续到会话状态的对象。如何单元测试会话状态

控制器做类似...

[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. 在静态实例化器中传递会话状态引用然后恢复f rom那。这将允许我嘲笑这个参数,并且一切都将是黄金。

    公共静态SessionManager FromSessionState(HttpSessionStateWrapper会话) { 返回会话[ “sessionmanager”]作为SessionManager ??新的SessionManager(); }

  2. 为SessionManager创建一个模拟并用它来测试控制器。

回答

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

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

+0

这是很好的建议。我一直很难写单元测试,所以任何简单的事情都很好。我还玩弄了一个独立的类,它将被用来将会话管理器保持到会话状态。我认为这可能会将问题分开,以便会话管理器只保存我的临时对象,然后sessionrepository负责保存它。 – yamspog 2010-09-18 17:25:35