我正在尝试在现有解决方案上设置单元测试,该解决方案包含使用较旧的第三方工具的MVC Web项目。这个工具大量使用HttpContext.Current
来完成它所做的事情,其中一个是相当复杂的依赖注入形式,用于实例化基本上是服务层对象。
因此,为了让这些对象在我的单元测试项目中实例化他们需要的一切,我需要创建自己的HttpContext
并将其分配给HttpContext.Current
。我的工作相对较好,但HttpContext.Current.Application
对象似乎存在问题。基本上,每当我添加一个对象时,使用HttpContext.Current.Application[key] = object;
或HttpContext.Current.Application.Add(key, object);
似乎都没有发生。
反编译System.Web
表示没有简单的方法来分配Appplication
属性,因为getter从工厂实例返回一个值,所以我的猜测是这个工厂正在生成一个新的应用程序每次引用HttpApplication.Application
属性时。是否有一些我缺少的东西,以确保这个值是持久的?
以下是我创建HttpContext.Current
对象的代码:
internal static class UnitTestUtilities
{
private static HttpApplication application;
private static HttpContext GetHttpContext(string url)
{
if (application == null)
{
application = new HttpApplication();
application.Init();
}
HttpContext.Current = new HttpContext(new HttpRequest("", url, ""),
new HttpResponse(new StringWriter()))
{
ApplicationInstance = application
};
//Call hacks to get context application set up
HttpContext.Current.ApplicationInstance.SetContext(HttpContext.Current);
HttpContext.Current.ApplicationInstance.AddApplicationState(HttpContext.Current.Application);
var testApplicationValue = "TEST";
var testApplicationValue2 = "TEST2";
HttpContext.Current.Application.Lock();
HttpContext.Current.Application["TEST"] = testApplicationValue;
HttpContext.Current.Application.Add("TEST2", testApplicationValue2);
HttpContext.Current.Application.UnLock();
//Issue is here: HttpContext.Current.Application still contains 0 items!
return HttpContext.Current;
}
#region System.Web hacks
private static void SetContext(this HttpApplication app, HttpContext context)
{
var prop = typeof(HttpApplication).GetField("_context", BindingFlags.NonPublic | BindingFlags.Instance);
prop.SetValue(app, context);
}
private static void AddApplicationState(this HttpApplication app, HttpApplicationState state = null)
{
if(state == null)
{
var ctor = typeof(HttpApplicationState).GetConstructor(
BindingFlags.Instance | BindingFlags.NonPublic,
null, new Type[] { }, new ParameterModifier[] { });
state = (HttpApplicationState)ctor.Invoke(new Object[] { });
}
var prop = typeof(HttpApplication).GetField("_state", BindingFlags.NonPublic | BindingFlags.Instance);
prop.SetValue(app, state);
}
#endregion
}