How I can mock HttpWebResponse with the property CharacterSet for unit test? In my code I am checking for HttpWebResponse.CharacterSet like below. I could mock HttpWebResponse but getting null reference exception while getting the property "CharacterSet". Please note I cannot setup "CharacterSet" in the mock as it is a read-only and non virtual property. I am using .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;
}
}
And the mock I have wriiten for HttpWebReponse is,
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;
}
This is the error I am getting while getting "CharacterSet",
I did further research into this, and it seems that you're not going to be able to do what you want. The issue is that the CharacterSet property derives itself using the headers collection. While you can override the Headers property, the CharacterSet property looks directly at the field. The only way the header collection field is set to a non-null value is via an internal constructor which copies it from something called cordata.
The result is that there's no safe way to mock the CharacterSet. I suppose you could use reflection to find the field and set it that way, but that seems like it wouldn't be a good idea as the implementation could change and break your test.