为假的 HttpContext 设置假的语言环境

Set fake locale for fake HttpContext

我正在对一段代码进行单元测试,这些代码在不同的语言环境中表现不同。我创建了一个伪造的 HttpContext,但需要为其设置 locale,但未能成功。这是我如何创建假 HttpContext:

    public static HttpContext FakeHttpContext(string requestUrl)
    {
        var httpRequest = new HttpRequest("", requestUrl, "");
        var stringWriter = new StringWriter();
        var httpResponce = new HttpResponse(stringWriter);
        var httpContext = new HttpContext(httpRequest, 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;
    }

前一段时间我不得不开放一些服务以更好地进行单元测试。我能够使用 HttpContextBase 和 HttpContextWrapper 实现这一点。你看过这些吗?我好像记得他们帮了我很多。

这里至少有一篇文章在谈论它。 C# unit testing API 2 call

您不需要模拟 HttpContext。可以使用 Thread.CurrentThread.CurrentCulture 属性更改文化:

Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-US");
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US");

这里已经讨论过了: Set Culture in an ASP.Net MVC app

终于解决了:

    /// <summary>
    /// Fake HTTPCONTEXT generator
    /// </summary>
    /// <param name="extention">Http context extention</param>
    /// <param name="domain">Http context domain</param>
    /// <param name="locale">Http context locale</param>
    /// <returns>Fake Http Context</returns>
    private static HttpContext FakeHttpContext(string extention, string domain, string locale = "en-US,en;q=0.8")
    {
        HttpWorkerRequest httpWorkerRequest = new SimpleWorkerRequestHelper(false, domain, extention, locale);
        return new HttpContext(httpWorkerRequest);
    }

SimpleWorkerRequestHelper 代码:

public class SimpleWorkerRequestHelper : SimpleWorkerRequest
{
    /// <summary>
    /// Whether the request is secure
    /// </summary>
    private string _domain;

    /// <summary>
    /// Whether the request is secure
    /// </summary>
    private string _locale;

    /// <summary>
    /// Initializes a new instance of the <see cref="SimpleWorkerRequestHelper" /> class.
    /// </summary>
    /// <param name="isSecure">Whether the helper request should be secure</param>
    public SimpleWorkerRequestHelper(bool isSecure, string domain = "", string extention = "/", string locale = "")
        : base(extention, AppDomain.CurrentDomain.BaseDirectory, string.Empty, string.Empty, new StringWriter())
    {
        _domain = domain;
        _locale = locale;
    }

    /// <devdoc>
    ///    <para>[To be supplied.]</para>
    /// </devdoc>
    public override String GetRemoteAddress()
    {
        if (string.IsNullOrEmpty(this._domain))
        {
            return base.GetRemoteAddress();
        }
        else
        {
            return this._domain;
        }
    }

    /// <devdoc>
    ///    <para>[To be supplied.]</para>
    /// </devdoc>
    public override String GetLocalAddress()
    {
        if (string.IsNullOrEmpty(this._domain))
        {
            return base.GetLocalAddress();
        }
        else
        {
            return this._domain;
        }
    }

    /// <summary>
    /// Overriding "GetKnownRequestHeader" in order to force "SimpleWorkerRequest" to return the fake value for locale needed for unit testing.
    /// </summary>
    /// <param name="index">Index associated with HeaderAcceptLanguage in lower level library</param>
    /// <returns>The language or the value from base dll</returns>
    public override string GetKnownRequestHeader(int index)
    {
        if (index == HttpWorkerRequest.HeaderAcceptLanguage && !string.IsNullOrEmpty(_locale))
        {
            return _locale;
        }
        else
        {
            return base.GetKnownRequestHeader(index);
        }
    }

}