Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/6.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
C# 在传统ASP.NET应用程序中进行单元测试以模拟HttpContext_C#_Asp.net_Unit Testing_Httpcontext - Fatal编程技术网

C# 在传统ASP.NET应用程序中进行单元测试以模拟HttpContext

C# 在传统ASP.NET应用程序中进行单元测试以模拟HttpContext,c#,asp.net,unit-testing,httpcontext,C#,Asp.net,Unit Testing,Httpcontext,我有一个方法: public DataSet someMethod() { List a = someObj.getList(name, integerId); } 现在,integerId是通过HttpContext.Current.Session变量获得的。 我已经为该方法编写了一个单元测试。但是由于测试在web进程之外运行,HttpContext.Current.Session返回null,测试失败 有什么解决方法吗?您需要为您的测试注入一个假的HttpContext,理想情况下

我有一个方法:

public DataSet someMethod()
{
    List a = someObj.getList(name, integerId);
}
现在,integerId是通过
HttpContext.Current.Session
变量获得的。 我已经为该方法编写了一个单元测试。但是由于测试在web进程之外运行,
HttpContext.Current.Session
返回null,测试失败


有什么解决方法吗?

您需要为您的测试注入一个假的
HttpContext
,理想情况下是作为
HttpContextBase
,这是一个可模拟但在其他方面相同的API

您可以将
HttpContext
包装在
HttpContextWrapper
中,以获得
HttpContextBase


阅读控制反转的各种技术,并找到一种适合您的技术。

首先,您必须初始化:

然后,您必须设置会话:(Necroskillz在中解释了执行此操作的方法)

以下代码段显示了它的工作原理:

[TestMethod]
public void TestMethod1()
{
    HttpContext.Current = new HttpContext(new HttpRequest("", "http://blabla.com", "") {},
                                          new HttpResponse(new StringWriter()));

    HttpContext.Current.SetFakeSession();

    HttpContext.Current.Session["foo"] = 1;

    Assert.AreEqual(1, HttpContext.Current.Session["foo"]);
}

我想这个问题的懒散答案应该是:学会使用,但我会继续提供一些指导

类不太可能需要HttpContext中的所有内容。您没有指定如何计算
整数ID
,但假设它是当前
会话状态的
会话ID
的散列。您的类实际上需要的只是某种方法来获取特定的
SessionId
;这不需要是一个完整的
HttpContext

interface ICurrentSessionIdProvider
{
     string SessionId { get; }
}
现在你们班有:

// Pull this from a constructor parameter so you can provide any implementation you want
private readonly ICurrentSessionIdProvider _sessionIdProvider;

public DataSet someMethod()
{
     int integerId = _sessionIdProvider.SessionId.GetHashCode();
     List a = someObj.getList(name, integerId);
}
现在,在单元测试中,模拟这种依赖关系变得很简单。像Moq和AutoFixture这样的工具甚至可以帮你,现在你的生活轻松愉快等等

当然,在实际应用程序中,您希望使用基于HttpContext的实现:

class HttpContextCurrentSessionIdProvider : ICurrentSessionIdProvider   
{
     // Pull this from a constructor parameter or however you see fit.
     private readonly HttpContext _httpContext;

     public SessionId => _httpContext.Current.Session.SessionId;
}  

在经典的ASP.NET中模拟HttpContext是很困难的。我建议您将对HttpContext.Session的引用包装在自己的mockable类中。数据访问层不应该依赖于HttpContext对象。是的,理想情况下应该是这样。然而,为了做到这一点,我的项目中有大量代码需要重新分解。
// Pull this from a constructor parameter so you can provide any implementation you want
private readonly ICurrentSessionIdProvider _sessionIdProvider;

public DataSet someMethod()
{
     int integerId = _sessionIdProvider.SessionId.GetHashCode();
     List a = someObj.getList(name, integerId);
}
class HttpContextCurrentSessionIdProvider : ICurrentSessionIdProvider   
{
     // Pull this from a constructor parameter or however you see fit.
     private readonly HttpContext _httpContext;

     public SessionId => _httpContext.Current.Session.SessionId;
}