Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 如何对会话状态进行单元测试_Asp.net Mvc_Unit Testing_Rhino Mocks_Session State - Fatal编程技术网

Asp.net mvc 如何对会话状态进行单元测试

Asp.net mvc 如何对会话状态进行单元测试,asp.net-mvc,unit-testing,rhino-mocks,session-state,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 =

我试图弄清楚如何对将自身保持为会话状态的对象进行单元测试

控制器执行如下操作

    [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; }
    }
我认为单元测试有两种方法

  • 在静态实例化器中,传入会话状态引用,然后从该引用还原。这将允许我模拟这个参数,一切都将是金色的

    来自SessionState的公共静态会话管理器(HttpSessionStateWrapper会话) { 以sessionmanager??new sessionmanager()的身份返回会话[“sessionmanager”]; }

  • 为SessionManager创建一个模拟,并将其用于测试控制器


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

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

    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
    ,并在生产期间使用基于会话的存根。如果您决定在其他地方(如DB或其他东西)持久化,这也有不需要更改的好处。只需实现一个新的
    ISessionManagerPersist

    ,这是一个很好的建议。我一直很难编写单元测试,所以任何让它更简单的东西都是好的。我也在考虑使用一个单独的类来将会话管理器持久化到会话状态。我认为这可能会将关注点分开,这样会话管理器就可以存储我的临时对象,然后sessionrepository将负责持久化它。