Модульное тестирование /интеграционное тестирование веб-API с помощью HttpClient в Visual Studio 2013

Я с трудом пытаюсь протестировать мой контроллер API с помощью Visual Studio 2013. Мое единственное решение имеет проект Web API и тестовый проект. В моем тестовом проекте у меня есть модульный тест с этим:

[TestMethod]
public void GetProduct()
{
    HttpConfiguration config = new HttpConfiguration();
    HttpServer _server = new HttpServer(config);

    var client = new HttpClient(_server);

    var request = new HttpRequestMessage
    {
        RequestUri = new Uri("http://localhost:50892/api/product/hello"),
        Method = HttpMethod.Get
    };

    request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    using (var response = client.SendAsync(request).Result)
    {
        Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);

        var test = response.Content.ReadAsAsync<CollectionListDTO>().Result;
    }
}

Я продолжаю получать 404 . Я попытался запустить мой API с одним экземпляром Visual Studio (IIS Express) и попытаться отладить этот модульный тест в другом экземпляре. Но не повезло. Я подтвердил, что могу поместить этот URL в браузер (когда отлаживается одна Visual Studio), и я вижу свой ответ JSON. Но я не могу понять, как заставить его работать с моим модульным тестом и HttpClient. Я пытался найти примеры в Интернете, но не могу найти один. Может кто-нибудь помочь?

ОБНОВЛЕНИЕ 1: Я пытался добавить маршрут, но ничего не произошло.

HttpConfiguration config = new HttpConfiguration();

// Added this line
config.Routes.MapHttpRoute(name: "Default", routeTemplate: "api/product/hello/");

HttpServer _server = new HttpServer(config);

var client = new HttpClient(_server);

[...rest of code is the same]

Вот мой API-контроллер

[HttpGet]
[Route("api/product/hello/")]
public IHttpActionResult Hello()
{
     return Ok();
}

Разрешение ОБНОВЛЕНИЯ: Я смог заставить его работать, если я обновлю HttpClient без HttpServer объект. Я все еще должен был бы иметь два экземпляра VS, работающего все же. 1 выполняется мой код API, а другой - для запуска модульного теста.

Вот рабочий метод.

[TestMethod]
public void Works()
{
    var client = new HttpClient(); // no HttpServer

    var request = new HttpRequestMessage
    {
        RequestUri = new Uri("http://localhost:50892/api/product/hello"),
        Method = HttpMethod.Get
    };

    request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    using (var response = client.SendAsync(request).Result)
    {
        Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
    }
}

Кто-нибудь знает, почему он не работает с HttpServer и HttpConfiguration передано в HttpClient? Я видел много примеров, которые используют это.

14 голосов | спросил duyn9uyen 27 Mayam16 2016, 08:19:18

2 ответа


0

Ссылка на следующую статью, которую я смог сделать ...

Интеграция ASP.NET Web API тестирование на хостинге в памяти

, работая с HttpServer и HttpConfiguration передается в HttpClient. В следующем примере я создал простой ApiController, который использует маршрутизацию атрибутов. Я настроил HttpConfiguration для сопоставления маршрутов атрибутов, а затем передал его новому HttpServer. Затем HttpClient может использовать настроенный сервер для выполнения тестовых вызовов интеграции с тестовым сервером.

public partial class MiscUnitTests {
    [TestClass]
    public class HttpClientIntegrationTests : MiscUnitTests {

        [TestMethod]
        public async Task HttpClient_Should_Get_OKStatus_From_Products_Using_InMemory_Hosting() {

            var config = new HttpConfiguration();
            //configure web api
            config.MapHttpAttributeRoutes();

            using (var server = new HttpServer(config)) {

                var client = new HttpClient(server);

                string url = "http://localhost/api/product/hello/";

                var request = new HttpRequestMessage {
                    RequestUri = new Uri(url),
                    Method = HttpMethod.Get
                };

                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                using (var response = await client.SendAsync(request)) {
                    Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
                }
            }
        }
    }

    public class ProductController : ApiController {
        [HttpGet]
        [Route("api/product/hello/")]
        public IHttpActionResult Hello() {
            return Ok();
        }
    }
}

Не было необходимости запускать другой экземпляр VS для интеграционного тестирования контроллера.

Следующая упрощенная версия теста также сработала.

var config = new HttpConfiguration();
//configure web api
config.MapHttpAttributeRoutes();

using (var server = new HttpServer(config)) {

    var client = new HttpClient(server);

    string url = "http://localhost/api/product/hello/";

    using (var response = await client.GetAsync(url)) {
        Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
    }
}

В вашем случае вам необходимо убедиться, что вы правильно настраиваете сервер в соответствии с настройками веб-API. Это будет означать, что вы должны зарегистрировать свои маршруты API с помощью объекта HttpConfiguration.

var config = new HttpConfiguration();
//configure web api
WebApiConfig.Register(config);
//...other code removed for brevity
ответил Nkosi 29 Maypm16 2016, 15:42:17
0

Что касается вашего вопроса о работе с HttpServer, я смог заставить его работать, как показано ниже: Это в .Net Framework. Это также можно использовать для тестирования интеграционных тестов конвейера WebAPI.

public static HttpResponseMessage ConfigureAndAct(string relativeApiUrl, HttpMethod httpMethodType, string bodyForPostMethod, int userid)
    {
        var uri = new Uri(string.Concat("http://localhost:10022", relativeApiUrl)); // Todo:Find free port at runtime


        HttpResponseMessage response;

        using (HttpConfiguration config = new HttpConfiguration())
        {
            config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;



            using (HttpRequestMessage request = new HttpRequestMessage()
            {
                Content = new StringContent(bodyForPostMethod, Encoding.UTF8, "application/json"),
                RequestUri = uri,
                Method = httpMethodType,
            })
            {


                using (var server = new HttpServer(config))
                {
                    using (var client = new HttpClient(server))
                    {
                        response = client.SendAsync(request, CancellationToken.None).Result;
                    }
                }
            }
        }

        return response;
    }




// Test GET
    -----------
    //Act    
var response = ConfigureWebApiForTest.ConfigureAndAct(uriToTest, HttpMethod.Get, string.Empty, userId);
    var result = response.Content.ReadAsAsync<Activity>().Result;
   //Assert
    Assert.IsTrue(response.StatusCode == HttpStatusCode.OK);
    Assert.IsNotNull(result);
    Assert.AreEqual(expectedUrl, result.SomeUrl);

    // Test POST
    ------------
    // Act
    HttpResponseMessage response = ConfigureWebApiForTest.ConfigureAndAct(uriToTest, HttpMethod.Post, body, userId);
 //Assert
    Assert.IsTrue(response.StatusCode == HttpStatusCode.OK);
ответил PKV 10 MaramSat, 10 Mar 2018 00:47:05 +03002018-03-10T00:47:05+03:0012 2018, 00:47:05

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132