在单元测试中设置HttpContext.Current.Session

212

我有一个正在尝试进行单元测试的Web服务。在服务中,它从HttpContext中提取多个值,如下所示:

 m_password = (string)HttpContext.Current.Session["CustomerId"];
 m_userID = (string)HttpContext.Current.Session["CustomerUrl"];

在我的单元测试中,我使用简单的工作者请求来创建上下文,就像这样:

SimpleWorkerRequest request = new SimpleWorkerRequest("", "", "", null, new StringWriter());
HttpContext context = new HttpContext(request);
HttpContext.Current = context;

然而,每当我尝试设置HttpContext.Current.Session的值时

HttpContext.Current.Session["CustomerId"] = "customer1";
HttpContext.Current.Session["CustomerUrl"] = "customer1Url";

我得到了一个空引用异常,指出HttpContext.Current.Session为空。

是否有任何方法在单元测试中初始化当前会话?


你尝试过这个方法了吗? - Raj Ranjhan
如果可以的话,请使用HttpContextBase - jrummell
14个回答

0
永远不要模拟..绝对不能!解决方案非常简单。为什么要伪造像HttpContext这样美丽的创作呢?
把会话下移到更低层次!(对大多数人来说,只需要这一行就足够理解,但下面详细解释)
现在我们是通过(string)HttpContext.Current.Session["CustomerId"]; 来访问它。将其改为
_customObject.SessionProperty("CustomerId")

当从测试中调用时,_customObject使用备用存储(DB或云键值[http://www.kvstore.io/])

但是当从真实应用程序中调用时,_customObject使用Session

这是如何做到的?好吧...依赖注入!

因此,测试可以设置会话(地下),然后调用应用程序方法,就好像它对会话一无所知。然后,测试秘密检查应用程序代码是否正确更新了会话。或者应用程序是否基于测试设置的会话值来行为。

实际上,尽管我说过“永远不要模拟”,但我们最终还是进行了模拟。因为我们不禁滑向了下一个规则,“在伤害最小的地方进行模拟!”。模拟巨大的HttpContext或模拟微小的会话,哪个伤害最小?别问我这些规则来自哪里。让我们只说是常识。这里有一篇关于不模拟的有趣阅读as unit test can kills us


0

@Ro Hit 的回答给了我很大的帮助,但是因为我不得不为身份验证单元测试伪造一个用户,所以我缺少用户凭据。因此,让我描述一下我是如何解决它的。

根据this,如果您添加方法

    // using System.Security.Principal;
    GenericPrincipal FakeUser(string userName)
    {
        var fakeIdentity = new GenericIdentity(userName);
        var principal = new GenericPrincipal(fakeIdentity, null);
        return principal;
    }

然后追加

    HttpContext.Current.User = FakeUser("myDomain\\myUser");

到达 TestSetup 方法的最后一行,你就完成了,用户凭证已经添加并准备好用于身份验证测试。

我还注意到 HttpContext 中可能需要其他部分,例如 .MapPath() 方法。有一个可用的 FakeHttpContext,在这里描述,可以通过 NuGet 安装。


0

0

尝试这种方式...

public static HttpContext getCurrentSession()
  {
        HttpContext.Current = new HttpContext(new HttpRequest("", ConfigurationManager.AppSettings["UnitTestSessionURL"], ""), new HttpResponse(new System.IO.StringWriter()));
        System.Web.SessionState.SessionStateUtility.AddHttpSessionStateToContext(
        HttpContext.Current, new HttpSessionStateContainer("", new SessionStateItemCollection(), new HttpStaticObjectsCollection(), 20000, true,
        HttpCookieMode.UseCookies, SessionStateMode.InProc, false));
        return HttpContext.Current;
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接