Модульное тестирование / интеграционное тестирование веб-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 без

2 ответов


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

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

, работая с HttpServer и a HttpConfiguration перешел в HttpClient. В следующем примере я создал простой ApiController который использует маршрутизацию атрибутов. Я настроил HttpConfiguration чтобы отобразить маршруты атрибутов, а затем передать его в новый HttpServer. The 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 с помощью


Что касается вашего вопроса о работе с 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);