Модульное тестирование IHttpActionResult без приведения типа возврата - PullRequest
2 голосов
/ 21 мая 2019

У меня есть контроллер веб-API с методом, подобным (усеченные нерелевантные биты):

[HttpGet]
public IHttpActionResult Order(int orderId) {
    // ...
    var response = new OrderResponse {
        Data = orderData,
        Message = message,
    };
    return Json(response);
}

У меня есть тест, который делает утверждение о значении ожидаемого JsonResult<OrderResponse>.Content.

Так как интерфейс IHttpActionResult не объявляет Content, я в настоящее время преобразую результат в модульном тесте в JsonResult. Однако для этого требуется, чтобы мой тест знал, как возврат реализован в моем контроллере, и я хотел бы добиться более слабой связи, если это возможно, чтобы мои тесты не прерывались при изменении реализации ответа.

[TestCase(-1, "The requested order (-1) was not found.")]
public void Test_Returns_NotFound_For_NonExistent_OrderId(int orderId, string expected) {
    var sut = new OrderController()
    // ...
    var result = sut.Order(orderId);

    // I am doing this to get access to `Content`:
    var materializedResult = result as JsonResult<OrderResponse>;

    expected.Should().BeEquivalentTo(materializedResult.Content.Message)
}

Ответы [ 2 ]

1 голос
/ 21 мая 2019

Вместо возврата Json(response) верните Ok(response).Вам не нужно указывать, что он отформатирован как JSON.Если клиент запрашивает JSON, приложение вернет JSON.(Предполагается, что вы используете согласование содержимого по умолчанию.)

Затем в модульном тесте вы можете извлечь свои данные из возвращенных IHttpActionResult следующим образом:

var actionResult = sut.Order(orderId);
var orderResponse = actionResult.ExecuteAsync(new CancellationToken())
    .Result.TryGetContentValue(out OrderResponse expected);

... ивы можете утверждать, что хотите, с помощью expected, и ваш тест не делает никаких предположений о том, как отформатирован ответ.

1 голос
/ 21 мая 2019

короче? Используйте только методы, доступные в интерфейсе!

  var controller = new ValuesController();
  controller.Configuration = new System.Web.Http.HttpConfiguration();
  controller.Request = new System.Net.Http.HttpRequestMessage();
  var result = controller.Get(1);

  var response = result.ExecuteAsync(new System.Threading.CancellationToken());
  String deserialized = response.Result.Content.ReadAsStringAsync().Result;
  Assert.AreEqual("\"value\"", deserialized);

IHttpActionResult содержит только один метод - ExecuteAsync. Так назови это! Он вернет HttpResponseMessage, который будет содержать контент, который вы ищете. Возможно, вы захотите сделать свои юнит-тесты асинхронными и фактически дождаться результата, но это должно помочь вам начать работу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...