#api #asp.net-core #data-binding #httpclient #nancy
#API #asp.net-core #привязка данных #httpclient #нэнси
Вопрос:
Я провожу некоторое интеграционное тестирование своего веб-API, который использует конечные точки NancyFX. У меня есть тест xUnit, создающий тестовый сервер для интеграционного теста
private readonly TestServer _server;
private readonly HttpClient _client;
public EventsModule_Int_Tester()
{
//Server setup
_server = new TestServer(new WebHostBuilder()
.UseStartup<Startup>());
_server.AllowSynchronousIO = true;//Needs to be overriden in net core 3.1
_client = _server.CreateClient();
}
Внутри метода тестирования я попробовал следующее
[Fact]
public async Task EventTest()
{
// Arrange
HttpResponseMessage expectedRespone = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
var data = _server.Services.GetService(typeof(GenijalnoContext)) as GenijalnoContext;
//Get come random data from the DBcontext
Random r = new Random();
List<Resident> residents = data.Residents.ToList();
Resident random_residnet = residents[r.Next(residents.Count)];
List<Apartment> apartments = data.Apartments.ToList();
Apartment random_Apartment = apartments[r.Next(apartments.Count)];
EventModel model = new EventModel()
{
ResidentId = random_residnet.Id,
ApartmentNumber = random_Apartment.Id
};
//Doesnt work
IList<KeyValuePair<string, string>> nameValueCollection = new List<KeyValuePair<string, string>> {
{ new KeyValuePair<string, string>("ResidentId", model.ResidentId.ToString()) },
{ new KeyValuePair<string, string>("ApartmentNumber", model.ApartmentNumber.ToString())}
};
var result = await _client.PostAsync("/Events/ResidentEnter", new FormUrlEncodedContent(nameValueCollection));
//Also Doesnt work
string json = JsonConvert.SerializeObject(model, Formatting.Indented);
var httpContent = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _client.PostAsync("/Events/ResidentEnter", httpContent);
//PostAsJsonAsync also doesnt work
// Assert
Assert.Equal(response.StatusCode, expectedRespone.StatusCode);
}
Модуль NancyFX запускает конечную точку и получает запрос, но без тела
Что я делаю не так? Обратите внимание, что конечная точка NancyFX не имеет проблем с преобразованием вызова Postman в допустимую модель.
Комментарии:
1. Можете ли вы показать подпись API на
/Events/ResidentEnter
конечной точке?2. @Andy обновил вопрос с помощью endpoint API
3. Вы сказали, что у PostMan нет проблем, можете ли вы также показать, что вы делаете в PostMan?
4. @Andy Я просто отправляю свойства EventModel в качестве параметров через тело в форме form-data. Обратите внимание, что работают как form-data, так и x-www-form-urlencoded. Я могу добавить картинку, если вы хотите
5. Если это работает в PostMan, но здесь это не работает… И ваша фактическая конечная точка попадает в ваши тесты (означает, что ваш хост httpclient настроен правильно), тогда должно быть, что вы отправляете данные не так, как в PostMan.
Ответ №1:
Хорошо, я исправил это, для любопытных проблема заключалась в том, что программа чтения тела NancyFX иногда неправильно начинает чтение тела запроса. Это означает, что позиция чтения потока не всегда равна 0 (начало).
Чтобы исправить это, вам нужно создать CustomBoostrapper, а затем переопределить функцию ApplicationStartup, чтобы вы могли настроить конвейер перед запросом, который устанавливает положение тела на 0
Код ниже
protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
{
base.ApplicationStartup(container, pipelines);
pipelines.BeforeRequest.AddItemToStartOfPipeline(ctx =>
{
ctx.Request.Body.Position = 0;
return null;
});
}