【问题标题】:ASP.NET MVC, HttpContext.Current is null while mocking a requestASP.NET MVC,HttpContext.Current 在模拟请求时为空
【发布时间】:2015-06-25 06:06:52
【问题描述】:
public async Task <ActionResult>Select(DWorkingTimeSelection dto) { 
    var session = HttpUtils.GetSeesion<User>("USER"); 
} 

public static T GetSeesion<T>(string key) where T : class
{ 
    if (HttpContext.Current == null) 
    { 
        return default(T);
    }
     return HttpContext.Current.Session[key] as T; 
}

public async Task <ActionResult>Select(DWorkingTimeSelection dto) { 
    var session = HttpUtils.GetSeesion<User>("USER"); 
} 

public static T GetSeesion<T>(string key) where T : class
{ 
    if (HttpContext.Current == null) 
    { 
        return default(T);
    } 
    return HttpContext.Current.Session[key] as T; 
}

我使用 nunti 来模拟一个请求。 我将 SessionStateItemCollection 添加到 Controller 的 ControllerContext 中。 我发现 HttpContext.Current 为空,但 Controller 的 Session[] 不为空,因为它来自 Controller 的 ControllerContext 。 那么在模拟请求时我应该怎么做才能避免 HttpContext.Current 为空

【问题讨论】:

    标签: asp.net-mvc unit-testing session mocking nunit


    【解决方案1】:

    你可以模拟 HttpContext:

        public static HttpContext FakeHttpContext(HttpRequest request)
        {
            var stringWriter = new StringWriter();
            var httpResponce = new HttpResponse(stringWriter);
            var httpContext = new HttpContext(request, httpResponce);
    
            var sessionContainer = new HttpSessionStateContainer(
                "id", 
                new SessionStateItemCollection(), 
                new HttpStaticObjectsCollection(), 
                10, 
                true, 
                HttpCookieMode.AutoDetect, 
                SessionStateMode.InProc, 
                false);
    
            httpContext.Items["AspSession"] =
                typeof(HttpSessionState).GetConstructor(
                    BindingFlags.NonPublic | BindingFlags.Instance, 
                    null, 
                    CallingConventions.Standard, 
                    new[] { typeof(HttpSessionStateContainer) }, 
                    null).Invoke(new object[] { sessionContainer });
    
            return httpContext;
        }
    
        [TestMethod]
        public void ActionTest()
        {
            var request = new HttpRequest(string.Empty, "url to the action that you are testing", string.Empty)
            {
                RequestType = "GET"
            };
            HttpContext.Current = FakeHttpContext(request);
    
            var controller = new YourController();
            //You need the get a Result property since it is an async action
            var result = controller.ActionToTest(//the parameters that your action expects).Result;
            Assert.IsNotNull(result);
        }
    

    编辑(回答评论中的问题)

    为了获得会话,您需要调用HttpContext.Current.Session 而不是HttpContext.Current.Session["id"],因为HttpContext.Current.Session["id"] 试图从您的会话中获取id 密钥。 一旦你将它存储在那里,它将通过这个调用可用。你可以测试一下:

    HttpContext.Current.Session["id"] = 5;
    Assert.AreEqual(HttpContext.Current.Session["id"],5);
    

    关于httpContext.Items 声明:

    (来自 MSDN)HttpContext.Items 是一个键/值集合,可用于在 HTTP 请求期间在IHttpModule 接口和IHttpHandler 接口之间组织和共享数据。

    您要求的语句,只需使用反射创建一个新的HttpSessionState 对象(因为它只有内部构造函数)将它与您之前创建的HttpSessionStateContainer 关联,并将其存储在@ 下的HttpContext.Items 987654334@。有趣的是HttpContext.Current.Session 实际上是HttpContext.Items["AspSession"] 的快捷方式。所以将 HttpSessionState 对象分配给AspSession 键是使HttpContext.Current.Session 工作的on。

    【讨论】:

    • 好吧,现在 HttpContext.Current 不为空。但是我还不能从 HttpContext.Current.Session["id"] 获取会话。你能解释一下声明 - httpContext.Items好吗?
    • 查看最新编辑。如果我的回答对您有帮助并解决了您的问题,请将其标记为 aswer
    • 关于 HttpRequest 实例化中的 URL 参数,它可以是任何形式,只要它格式正确即可:http://test.com/Controller/Action 可以解决问题。
    【解决方案2】:

    好吧,在像 Alex Art 所说的那样嘲笑 HttpContext 之后。

    调用下面的方法就可以了。

    var sessionItems = new SessionStateItemCollection();
            sessionItems["SessionKey"] = new MyCustomObject();
            SessionStateUtility.AddHttpSessionStateToContext(fakeHttpContext,
                new HttpSessionStateContainer(SessionNameStorage.Suser,
                              sessionItems,
                              new HttpStaticObjectsCollection(),
                              20000,
                              true,
                              HttpCookieMode.AutoDetect,
                              SessionStateMode.InProc,
                              false
                          ));
    

    【讨论】:

      猜你喜欢
      • 2010-10-13
      • 2023-03-09
      • 2012-08-02
      • 2011-04-24
      • 2011-01-16
      • 1970-01-01
      • 2010-11-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多