Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a mock HttpWebRequest and HttpWebResponse object

How to create mock HttpWebRequest and HttpWebResponse object I am trying to unittest the following piece of code

HttpWebrequest request;   

if (null != request)
{                         
    var response = (HttpWebResponse)request.GetResponse();
    using (var sr = new StreamReader(response.GetResponseStream()))
    {
        jsonResult = sr.ReadToEnd();
    }

    var myRecords = SerializationHelper.Deserialize<Records>(jsonResult);
}
like image 480
Steve Avatar asked Apr 22 '13 23:04

Steve


People also ask

What is HttpWebResponse?

This class contains support for HTTP-specific uses of the properties and methods of the WebResponse class. The HttpWebResponse class is used to build HTTP stand-alone client applications that send HTTP requests and receive HTTP responses.

What is HttpWebRequest C#?

The HttpWebRequest class provides support for the properties and methods defined in WebRequest and for additional properties and methods that enable the user to interact directly with servers using HTTP.


2 Answers

You can use reflections to rewrite fields of response you need to adjust to create mock response. Here is example of creating a response with status code 429:

HttpWebResponse response = (HttpWebResponse)request.GetResponse();
statusCode = (int)response.StatusCode;
ActivateCallback(responseCallback, response, url, string.Empty);

var fieldStatusCode = response.GetType().GetField("m_StatusCode", 
                                                   BindingFlags.Public | 
                                                   BindingFlags.NonPublic | 
                                                   BindingFlags.Instance);
var statusCodeNew = (HttpStatusCode)409;
fieldStatusCode.SetValue(response, statusCodeNew);
string responceBody = "{\"error\":{\"code\":\"AF429\",\"message\":\"Too many requests. Method=GetContents, PublisherId=00000000-0000-0000-0000-000000000000\"}}";

var propStream = response.GetType().GetField("m_ConnectStream", 
                                              BindingFlags.Public | 
                                              BindingFlags.NonPublic | 
                                              BindingFlags.Instance);

System.IO.MemoryStream ms = new System.IO.MemoryStream(
                           System.Text.Encoding.UTF8.GetBytes(responceBody));
propStream.SetValue(response, ms);
ms.Position = 0;
like image 152
Natalie Polishuk Avatar answered Sep 20 '22 16:09

Natalie Polishuk


It's an old question, but maybe it can be usefull for someone. Adapted from this question in msdn:

private static WebResponse CreateWebResponse(HttpStatusCode httpStatus, MemoryStream responseObject)
{
  TcpListener l = new TcpListener(IPAddress.Loopback, 0);
  l.Start();
  int port = ((IPEndPoint)l.LocalEndpoint).Port;
  l.Stop();

  // Create a listener.
  string prefix = "http://localhost:" + port + "/";
  HttpListener listener = new HttpListener();
  listener.Prefixes.Add(prefix);
  listener.Start();
  try
  {
    listener.BeginGetContext((ar) =>
    {
      HttpListenerContext context = listener.EndGetContext(ar);
      HttpListenerRequest request = context.Request;

      // Obtain a response object.
      HttpListenerResponse response = context.Response;

      response.StatusCode = (int)httpStatus;

      // Construct a response.
      if (responseObject != null)
      {
        byte[] buffer = responseObject.ToArray();

        // Get a response stream and write the response to it.
        Stream output = response.OutputStream;
        output.Write(buffer, 0, buffer.Length);
      }

      response.Close();
    }, null);

    WebClient client = new WebClient();
    try
    {
      WebRequest request = WebRequest.Create(prefix);
      request.Timeout = 30000;
      return request.GetResponse();
    }
    catch (WebException e)
    {
      return e.Response;
    }
  }
  finally
  {
    listener.Stop();
  }

  return null;
}

In here you can write whatever you want in responseObject or leave it null.

like image 29
Miquel Avatar answered Sep 20 '22 16:09

Miquel