2014-10-02 23 views
1

我正在爲我們開發的一些Web服務編寫單元測試。我有一個[TestMethod]作爲休息發佈到web服務。很好的工作,但它不會觸發我創建的事件處理方法。通過調試,我注意到在執行testmethod之後,事件處理程序正在獲取排除項。它去testcleanup。Webclient UploadStringCompleted事件未被調用

有沒有人遇到過這個問題?下面的代碼

[TestMethod,TestCategory("WebServices")] 
     public void ValidateWebServiceGetUserAuthToken() 
     { 
      string _jsonstringparams = 
       "{ \"Password\": \"xxx\", \"UserId\": \"xxxx\"}"; 
      using (var _requestclient = new WebClient()) 
      { 
       _requestclient.UploadStringCompleted += _requestclient_UploadStringCompleted; 
       var _uri = String.Format("{0}?format=Json", _webservicesurl); 
       _requestclient.Headers.Add(HttpRequestHeader.ContentType, "application/json"); 
       _requestclient.UploadStringAsync(new Uri(_uri), "POST", _jsonstringparams); 
      } 
    } 

    void _requestclient_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e) 
    { 
     if (e.Result != null) 
     { 
      var _responsecontent = e.Result.ToString(); 
      Console.WriteLine(_responsecontent); 
     } 
     else 
     { 
      Assert.IsNotNull(e.Error.Message, "Test Case Failed"); 
     } 
    } 

回答

0

的問題是在於UploadStringAsync返回void(即它的發射後不管),並沒有本質上讓你檢測完成。

有幾個選項。第一個選項(我推薦的選項)是使用HttpClient,並使用PostAsync方法 - 您可以使用await。在這種情況下,我會做這樣的事情:

[TestMethod, TestCategory("WebServices")] 
public async Task ValidateWebServiceGetUserAuthToken() 
{ 
    string _jsonstringparams = 
     "{ \"Password\": \"xxx\", \"UserId\": \"xxxx\"}"; 
    using (var httpClient = new HttpClient()) 
    { 
     var _uri = String.Format("{0}?format=Json", _webservicesurl); 
     var stringContent = new StringContent(_jsonstringparams); 
     stringContent.Headers.ContentType = new MediaTypeHeaderValue("application/json"); 
     HttpResponseMessage response = await httpClient.PostAsync(_uri, stringContent); 
     // Or whatever status code this service response with 
     Assert.AreEqual(HttpStatusCode.Accepted, response.StatusCode); 
     var responseText = await response.Content.ReadAsStringAsync(); 
     // TODO: something more specific to your needs 
     Assert.IsTrue(!string.IsNullOrWhiteSpace(responseText)); 
    } 
} 

另一種選擇是改變你的完整事件處理信號返回到您的測試上載完成,並在您的測試,等待事件發生。例如:

[TestMethod, TestCategory("WebServices")] 
public void ValidateWebServiceGetUserAuthToken() 
{ 
    string _jsonstringparams = 
     "{ \"Password\": \"xxx\", \"UserId\": \"xxxx\"}"; 
    using (var _requestclient = new WebClient()) 
    { 
     _requestclient.UploadStringCompleted += _requestclient_UploadStringCompleted; 
     var _uri = String.Format("{0}?format=Json", _webservicesurl); 
     _requestclient.Headers.Add(HttpRequestHeader.ContentType, "application/json"); 
     _requestclient.UploadStringAsync(new Uri(_uri), "POST", _jsonstringparams); 
     completedEvent.WaitOne(); 
    } 
} 

private ManualResetEvent completedEvent = new ManualResetEvent(false); 
void _requestclient_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e) 
{ 
    if (e.Result != null) 
    { 
     var _responsecontent = e.Result.ToString(); 
     Console.WriteLine(_responsecontent); 
    } 
    else 
    { 
     Assert.IsNotNull(e.Error.Message, "Test Case Failed"); 
    } 
    completedEvent.Set(); 
} 
+0

工程!謝謝。兩種方式都有效。我正在考慮Async方法,但沒有想到ManualResetEvent。感謝您的答覆! – Don 2014-10-02 20:16:37

0

除了上述問題的答案的帖子,我也加入到支持httpwebresponse所以我不必等待事件的方法。

public static AuthTokenResponse GetUserToken(string username, string password) 
     { 
      string _jsonstringparams = 
       String.Format("{{ \"Password\": \"{0}\", \"UserId\": \"{1}\"}}", password, username); 
      string _webservicesurl = ConfigurationManager.AppSettings["WebservicesUrl"]; 
      HttpWebRequest _requestclient = (HttpWebRequest)WebRequest.Create(String.Format("{0}?format=Json", _webservicesurl)); 
      _requestclient.ContentType = "application/json"; 
      _requestclient.Method = "POST"; 
      using (var streamWriter = new StreamWriter(_requestclient.GetRequestStream())) 
      { 
       streamWriter.Write(_jsonstringparams); 
       streamWriter.Flush(); 
       streamWriter.Close(); 
       var httpResponse = (HttpWebResponse)_requestclient.GetResponse(); 
       using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) 
       { 
        _responsecontent = streamReader.ReadToEnd(); 
       } 
       AuthTokenResponse _clienttoken = JsonConvert.DeserializeObject<AuthTokenResponse>(_responsecontent); 
       return _clienttoken; 
      } 
     }