2013-04-22 27 views
10

Làm thế nào để tạo ra mô hình HttpWebRequest và HttpWebResponse đối tượng Tôi cố gắng để UnitTest các đoạn mã sau đâyLàm thế nào để tạo ra một đối tượng giả HttpWebRequest và HttpWebResponse

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); 
} 
+0

Bạn muốn mô phỏng/mô phỏng hành vi nào? – mellamokb

+0

đã cập nhật câu hỏi của tôi ở trên – Steve

+0

Bạn có cần giả lập mã đó không? Hoặc sẽ chế nhạo 'jsonResult' là đủ? – Guvante

Trả lời

4

Bạn không thể tạo mô hình cho HttpWebResponse, chứ không phải chế giễu ra HttpWebResponse đang bao bọc cuộc gọi phía sau một giao diện, và giả lập giao diện đó.

0

Tôi chưa từng sử dụng nó nhưng khung Moles sẽ cho phép bạn thực hiện những gì bạn đang cố gắng làm. xem here để biết ví dụ chặn các cuộc gọi đến DateTime.Now.

2

Đó là một câu hỏi cũ, nhưng có lẽ nó có thể hữu ích cho ai đó. Được điều chỉnh từ 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; 
} 

Tại đây bạn có thể viết bất kỳ điều gì bạn muốn trả lờiKhông chấp nhận hoặc để trống.

0

Một HttpResponse giả có thể trông giống như ví dụ này:

public SenHttpMockResponse(HttpListenerContext context) 
{ 
    HttpListenerResponse response = context.Response; 
    response.Headers.Add("Content-type", @"application/json"); 
    JObject message = JObject.Parse(@"{'SomeParameterName':'ParameterValue'}"); 
    StreamWriter writer = new StreamWriter(response.OutputStream); 
    writer.Write(message); 
    writer.Close(); 
} 

Mở mặc định mã đáp ứng là 200 trong trường hợp này, nhưng bạn cũng có thể điều chỉnh với Response.StatusCode = 400;

Để thử một yêu cầu, bạn có thể sử dụng ví dụ một công cụ gỡ lỗi. Ví dụ: Firefox addon HttpRequester khá thú vị. Bạn có thể thực hiện tất cả các loại yêu cầu và bạn cũng sẽ thấy phản hồi của mình. Một công cụ hữu ích của nó tôi sẽ nói

0

Bạn cũng có thể sử dụng trình định dạng SOAP để xây dựng một HttpWebRequest giả. Đầu tiên nắm bắt HttpWebRequest bạn muốn giả lập như một chuỗi, sau đó bạn có thể tùy chỉnh nó trong thử nghiệm đơn vị của bạn và xây dựng lại HttpWebRequest bằng cách deserializing chuỗi.

Dưới đây là một ví dụ:

static void Main(string[] args) 
    { 
     SoapFormatter formatter = new SoapFormatter(); 

     HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create("http://www.google.com"); 
     HttpWebResponse resp = (HttpWebResponse)myReq.GetResponse(); 

     // save this soapRequest as a string and customize it for your mocking up 
     MemoryStream target = new MemoryStream(); 
     using(target) 
     { 
      formatter.Serialize(target, resp); 
     } 
     string soapRequest = Encoding.UTF8.GetString(target.GetBuffer()); 

     // now you can use the string to reconstruct the object from the string without needing anything special (other than substituting your own values into the XML) 
     HttpWebResponse myMockedObject = (HttpWebResponse)formatter.Deserialize(
      new MemoryStream(Encoding.UTF8.GetBytes(soapRequest))); 
    } 
1

Trong một dự án tôi đã làm việc trên, tôi cần phải làm một số trọng trong một dịch vụ ASMX web đã được ném lỗi chỉ trong sản xuất để tìm hiểu những gì XML dịch vụ đã thực sự phát lại. Để làm được điều đó, tôi phải tạo một đối tượng HttpWebResponse mới. Bí quyết cơ bản là sử dụng Activator.CreateInstance (bỏ qua thực tế là hàm tạo không được dùng nữa). Trong ví dụ dưới đây, tôi đang tận dụng thực tế rằng tôi đã đơn giản nhân bản một đối tượng HttpWebResponse hiện có và thiết lập lại luồng, nhưng kỹ thuật sẽ giống nhau để tạo một hoàn toàn từ đầu.

string sLastXML; 

    public string LastXML 
    { 
     get 
     { 
      return sLastXML; 
     } 
    } 

    protected override System.Net.WebResponse GetWebResponse(System.Net.WebRequest request) 
    { 
     // Get the XML Returned 
     System.Net.HttpWebResponse oResponse = (System.Net.HttpWebResponse)request.GetResponse(); 
     System.IO.Stream oStream = oResponse.GetResponseStream(); 
     byte[] inStream = new byte[oResponse.ContentLength]; 
     int iActual = 0; 
     while (iActual < oResponse.ContentLength) 
     { 
      iActual += oStream.Read(inStream, iActual, (int)oResponse.ContentLength - iActual); 
     } 
     sLastXML = System.Text.Encoding.Default.GetString(inStream); 

     // Create new stream 
     System.IO.MemoryStream oNewStream = new System.IO.MemoryStream(); 
     oNewStream.Write(inStream, 0, (int)oResponse.ContentLength); 
     oNewStream.Position = 0; 

     // Create new response object 
     System.Net.HttpWebResponse oNewResponse = (System.Net.HttpWebResponse)System.Activator.CreateInstance(typeof(System.Net.HttpWebResponse)); 
     System.Reflection.PropertyInfo oInfo = oNewResponse.GetType().GetProperty("ResponseStream", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.FlattenHierarchy); 
     oInfo.SetValue(oNewResponse,oNewStream); 
     System.Reflection.FieldInfo oFInfo = oNewResponse.GetType().GetField("m_HttpResponseHeaders", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.FlattenHierarchy); 
     oFInfo.SetValue(oNewResponse, oFInfo.GetValue(oResponse)); 
     oFInfo = oNewResponse.GetType().GetField("m_ContentLength", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.FlattenHierarchy); 
     oFInfo.SetValue(oNewResponse, oFInfo.GetValue(oResponse)); 
     oFInfo = oNewResponse.GetType().GetField("m_Verb", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.FlattenHierarchy); 
     oFInfo.SetValue(oNewResponse, oFInfo.GetValue(oResponse)); 
     oFInfo = oNewResponse.GetType().GetField("m_StatusCode", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.FlattenHierarchy); 
     oFInfo.SetValue(oNewResponse, oFInfo.GetValue(oResponse)); 
     oFInfo = oNewResponse.GetType().GetField("m_StatusDescription", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.FlattenHierarchy); 
     oFInfo.SetValue(oNewResponse, oFInfo.GetValue(oResponse)); 
     oFInfo = oNewResponse.GetType().GetField("m_IsMutuallyAuthenticated", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.FlattenHierarchy); 
     oFInfo.SetValue(oNewResponse, oFInfo.GetValue(oResponse)); 
     oFInfo = oNewResponse.GetType().GetField("m_IsVersionHttp11", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.FlattenHierarchy); 
     oFInfo.SetValue(oNewResponse, oFInfo.GetValue(oResponse)); 
     oFInfo = oNewResponse.GetType().GetField("m_MediaType", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.FlattenHierarchy); 
     oFInfo.SetValue(oNewResponse, oFInfo.GetValue(oResponse)); 
     oFInfo = oNewResponse.GetType().GetField("m_Uri", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.FlattenHierarchy); 
     oFInfo.SetValue(oNewResponse, oFInfo.GetValue(oResponse)); 
     oFInfo = oNewResponse.GetType().GetField("m_UsesProxySemantics", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.FlattenHierarchy); 
     oFInfo.SetValue(oNewResponse, oFInfo.GetValue(oResponse)); 

     oNewResponse.Cookies = oResponse.Cookies; 

     return oNewResponse; 


    } 
0

Bạn có thể sử dụng phản xạ để viết lại các trường phản hồi bạn cần điều chỉnh để tạo phản hồi giả. Dưới đây là ví dụ về cách tạo phản hồi với mã trạng thái 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; 
Các vấn đề liên quan