Тестування блоку ASP.NET WebApi за допомогою Request.CreateResponse


147

Я намагаюся написати кілька тестів для мого ApiController і зіткнувся з деякими проблемами. Існує приємний метод розширення під назвою Request.CreateResponse, який дуже допомагає генерувати відповідь.

public HttpResponseMessage Post(Product product)
{
  var createdProduct = repo.Add(product);
  return this.Request.CreateResponse(HttpStatusCode.Created, createdProduct);
}

Чи є спосіб знущатися над CreateResponse без використання часткових макетів або прямого використання "нового HttpResponseMessage (...)"?


1
Чому ти хочеш знущатися над CreateResponse? Чому б не стверджувати про повернуті HttpResponseMessage Contentта StatusCodeвластивості, що встановлені правильні значення?
nemesv

3
Якщо я запускаю цей метод форми тестових одиниць, він виключається, за винятком того, що конфігурація не встановлена.
аса

1
Гаразд, сором мені, мені просто потрібно було це написати.Request.CreateResponse (HttpStatusCode.Accepted, createdProduct, GlobalConfiguration.Configuration)
asa

Відповіді:


243

Ще один спосіб вирішити це - зробити наступне:

controller.Request = new HttpRequestMessage();
controller.Request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, 
                                  new HttpConfiguration());

Якщо ви переходите до версії webapi 5.0, вам потрібно буде змінити це на:

controller.Request = new HttpRequestMessage();
controller.Request.SetConfiguration(new HttpConfiguration());

Причина, чому вам потрібно це зробити, полягає в тому, що ви повинні бути Requestзаповнені на контролері, інакше методи розширення Requestне будуть працювати. Ви також повинні мати HttpConfigurationнабір Запити, в іншому випадку маршрутизація та інші частини трубопроводу не працюватимуть належним чином.


Так, це може також працювати, але, схоже, Request.CreateResponse також працює.
аса

4
Додавання GlobalConfiguration.Configuration все ще залишає запит нульовим. Налаштування Запити працювало для мене, проте це ще не закінчило моїх проблем, оскільки моя дія також дзвонила Url.Link, а назва маршруту не визначалася.
дурить

Допомога по налаштуванню маршруту stackoverflow.com/questions/11779311 / ...
foolshat

Встановлення ControllerContext після цього дзвінка дає мені і цю помилку, але тільки з WebApi 5.0.0. Але якщо я встановив об’єкт HttpConfiguration на Запит останнього , він працює добре.
mikebridge

Це прекрасно працює, але я не розумію, чому це працює. Чи могли б ви це детальніше пояснити у відповіді?
Jan_V

24

Ви можете встановити об’єкт контролера для перевірки на кшталт цього:

var config = new HttpConfiguration();
var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/api/products");
var route = config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}");
var routeData = new HttpRouteData(route, new HttpRouteValueDictionary { { "controller", "products" } });

controller.ControllerContext = new HttpControllerContext(config, routeData, request);
controller.Request = request;
controller.Request.Properties[HttpPropertyKeys.HttpConfigurationKey] = config;

Скопійовано з вичерпної публікації блогу Петра Простова на веб-API ASP.NET .


1
Можливо, вас також зацікавлять документи MS, пов’язані з цим: docs.microsoft.com/en-us/aspnet/web-api/overview/… Можливо, вам також потрібно буде додати посилання на System.Web.Http та System.Net. Http
Аарон Гофман

4

Для веб-API 2 ви можете просто додати

controller.Request = new HttpRequestMessage();
controller.Configuration = new HttpConfiguration();

Як так

[TestMethod]
public void GetReturnsProduct()
{
    // Arrange
    var controller = new ProductsController(repository);
    controller.Request = new HttpRequestMessage();
    controller.Configuration = new HttpConfiguration();

    // Act
    var response = controller.Get(10);

    // Assert
    Product product;
    Assert.IsTrue(response.TryGetContentValue<Product>(out product));
    Assert.AreEqual(10, product.Id);
}

Важливо встановити Запит та конфігурація на контролері. В іншому випадку тест не вдасться за допомогою ArgumentNullException або InvalidOperationException.

Дивіться тут для отримання додаткової інформації.


1

WebAPI 1 тут із аналогічною проблемою з використанням VB.

Мені вдалося провести гібридні відповіді, щоб це було так просто, як це:

Dim request As HttpRequestMessage = New HttpRequestMessage()
Return request.CreateResponse(HttpStatusCode.BadRequest, myCustomClassObject, GlobalConfiguration.Configuration)

Просто розміщуйте повідомлення, якщо це допоможе комусь.


0

У своєму тестовому класі створіть екземпляр класу контролера. напрvar customerController= new CustomerController();

customerController.Request = new HttpRequestMessage();
customerController.Request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, new HttpConfiguration());
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.