Указание содержимого httprequestmessage для модульного теста веб-api

У меня есть метод контроллера веб-API, который я хочу протестировать. Требуется HttpRequestMessage, но я не могу понять, как установить контент, который я хочу передать. Можно ли создать / имитировать HttpRequestMessage, чтобы я мог дать ему string, который я хочу сделать результатом await request.Content.ReadAsStringAsync() ?

Это мой метод контроллера:

[HttpPost]
public async Task<HttpResponseMessage> Post(HttpRequestMessage request)
{
    var data = await request.Content.ReadAsStringAsync();
    //do something with data
}

Я могу легко создать HttpRequestMessage с его конструктором без параметров, но я не могу понять, как установить для содержимого значимое значение. Я бы хотел, чтобы мой тест работал в следующих направлениях:

[TestMethod]
public async Task PostMethodWorks()
{
    var controller = new MyController();

    var data = "this will be JSON";
    var httpRequestMessage = new HttpRequestMessage();
    //set the content somehow so that httpRequestMessage.Content.ReadAsStringAsync returns data

    var response = await controller.Post(httpRequestMessage);

    //assert something about the response here
}

Можно ли установить значение содержимого для некоторого JSON, или мне нужно будет изменить метод, чтобы он принимал другой параметр?

(Для большего контекста, причина, по которой я хочу использовать метод в HttpRequestMessage, заключается в том, что я работаю над устаревшей кодовой базой, в которой есть множество методов контроллера, которые принимают HttpRequestMessage.)

Это похоже на XY проблема, поскольку в идеале действия веб-API не принимают HttpRequestMessage в качестве аргумента. Что вы делаете со строкой после извлечения ее из запроса?

Nkosi 13.09.2018 18:56

Я немного разобрался, почему унаследованный код написан так. Кажется, что большая часть нашего клиентского кода использует jQuery.post, который кодирует данные как application/x-www-form-urlencoded. Если метод контроллера принимает HttpRequestMessage, он может понимать сериализованные данные независимо от кодировки, но если метод принимает DTO, кодировка должна быть правильной (то есть application/json, если сериализован). Это означает, что изменение настроек jQuery для использования кодировки JSON по умолчанию будет критическим изменением для методов, которые принимают DTO (и передают несериализованные данные).

Tim 17.09.2018 11:26

По сути, причина странного использования HttpRequestMessage в качестве параметра метода контроллера заключается в том, что мы не кодировали должным образом публикуемые данные, но теперь, когда существует сочетание подходов, стандартизировать их сложно.

Tim 17.09.2018 11:26
7
3
6 772
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Is it possible to set the value of the content to some JSON

да

Вы можете использовать любой из множества производных классов HttpContent. Поскольку в этом случае вы хотите отправить контент JSON, вы захотите использовать StringContent class

Например

[TestMethod]
public async Task PostMethodWorks() {
    //Arrange
    var controller = new MyController();

    var data = "this will be JSON";
    var httpRequestMessage = new HttpRequestMessage();

    //set the content somehow so that httpRequestMessage.Content.ReadAsStringAsync returns data 
    httpRequestMessage.Content = new StringContent(data, Encoding.UTF8, "application/json");


    //Act
    var response = await controller.Post(httpRequestMessage);

    //Assert
    //assert something about the response here
}

Однако это похоже на XY проблема, поскольку в идеале действия веб-API не принимают HttpRequestMessage в качестве аргумента.

or will I need to change the method so it takes in a different parameter?

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

Другие вопросы по теме