我正在试图弄清楚如何对我的对象进行单元测试,使其自身保持会话状态。
控制器执行类似......
的操作 [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; }
}
我认为单元测试有两种方法......
在静态实例化器中传递会话状态引用,然后从中恢复。这将允许我模拟这个参数,一切都会很好。
public static SessionManager FromSessionState(HttpSessionStateWrapper session) { 返回会话[“sessionmanager”]作为SessionManager ??新的SessionManager(); }
为SessionManager创建一个模拟器并将其用于测试控制器。
答案 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
。