2010-09-17 95 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