模拟HttpContext.Current应用程序不会持久化

时间:2018-01-17 17:51:27

标签: c# asp.net unit-testing httpcontext

我正在尝试在现有解决方案上设置单元测试,该解决方案包含使用较旧的第三方工具的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
}

0 个答案:

没有答案