Событие WebClient UploadStringCompleted не вызывается

1

Я пишу модульные тесты для некоторых веб-сервисов, которые мы разработали. У меня есть [TestMethod], который отправляется в веб-сервис в качестве покоя. Отлично работает, однако он не вызывает метод обработчика событий, который я создал. Благодаря отладке я заметил, что обработчик событий получает excluder после выполнения метода testmethod. Он идет на проверку очистки.

Кто-нибудь столкнулся с этой проблемой? Здесь код

 [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");
        }
    }
Теги:
webclient

2 ответа

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. Спасибо за ответ!
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;
            }
        }

Ещё вопросы

Сообщество Overcoder
Наверх
Меню