代码之家  ›  专栏  ›  技术社区  ›  Vijayanath Viswanathan

具有属性CharacterSet值的模拟HttpWebResponse

  •  3
  • Vijayanath Viswanathan  · 技术社区  · 6 年前

    如何使用单元测试的属性CharacterSet模拟HttpWebResponse?在我的代码中我正在检查HttpWebResponse.CharacterSet就像下面一样。我可以模拟HttpWebResponse,但是在获取属性“CharacterSet”时得到空引用异常。请注意,我无法在mock中设置“CharacterSet”,因为它是只读的非虚拟属性。我正在使用.Net 4.6.1

    public string ReadResponse(HttpWebResponse response)
        {
            var encoding = (response.CharacterSet == null || response.CharacterSet == "") ? Encoding.UTF8 : Encoding.GetEncoding(response.CharacterSet);
            using (var stream = response.GetResponseStream())
            {
                var reader = new StreamReader(stream, encoding);
                var responseString = reader.ReadToEnd();
                return responseString;
            }
        }
    

    我为HttpWebReponse写的模拟是,

    public static HttpWebResponse CreateRequestWithResponse(string responseContent)
        {
    
            var response = new Mock<HttpWebResponse>(MockBehavior.Loose);
            var responseStream = new MemoryStream(Encoding.UTF8.GetBytes(responseContent));
            response.Setup(c => c.StatusCode).Returns(HttpStatusCode.OK);
            response.Setup(c => c.ContentType).Returns("text/xml;charset=\"utf-8\"");
            response.Setup(c => c.GetResponseStream()).Returns(responseStream);
    
            var request = new Mock<HttpWebRequest>();
            request.Setup(a => a.ContentType).Returns("text/xml;charset=\"utf-8\"");
            request.Setup(s => s.GetResponse()).Returns(response.Object);
    
            return response.Object;
        }
    

    这是我在获取“CharacterSet”时遇到的错误,

    enter image description here

    2 回复  |  直到 6 年前
        1
  •  1
  •   Andy    6 年前

    我对此做了进一步的研究,看来你不能随心所欲。问题是CharacterSet属性使用headers集合派生自身。虽然可以重写Headers属性,但CharacterSet属性直接查看字段。将头集合字段设置为非空值的唯一方法是通过内部构造函数将其从称为cordata的内容中复制。

        2
  •  2
  •   NineBerry    6 年前

    了解 source code 您可以手动设置 HttpWebResponse 类的Get处理程序中使用的 CharacterSet

    public static HttpWebResponse CreateRequestWithResponse(string responseContent)
    {
        var response = new Mock<HttpWebResponse>(MockBehavior.Loose);
        var responseStream = new MemoryStream(Encoding.UTF8.GetBytes(responseContent));
        response.Setup(c => c.StatusCode).Returns(HttpStatusCode.OK);
        response.Setup(c => c.ContentType).Returns("text/xml;charset=\"utf-8\"");
        response.Setup(c => c.GetResponseStream()).Returns(responseStream);
    
        HttpWebResponse result = response.Object;
    
        // Set private field behind CharacterSet property
        var prop = typeof(HttpWebResponse).GetField("m_CharacterSet", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
        prop.SetValue(result, "utf-8");
    
        // Set private field used in CharacterSet getter
        prop = typeof(HttpWebResponse).GetField("m_HttpResponseHeaders", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
        prop.SetValue(result, new WebHeaderCollection());
    
        return result;
    }
    

    这取决于内部实施。所以,如果微软改变了 HttpWeb响应 同学们,你们的考试将会被打破。