// ApiClient.cs
// Example methods that call REST API
public async Task GetPets(string searchQuery, int skip = 0, int take = 20, bool includeAdopted = false)
{
// Logic that makes HTTP request to something like 'GET {baseUri}/pets'
}
public async Task GetEmployees(string searchQuery, int skip = 0, int take = 20)
{
// Logic that makes HTTP request to something like 'GET {baseUri}/employees'
}
// RequestHandler.cs
// Example method expecting Func that doesn't work yet
public static async Task PagedLookupAsync(Func getResponse, string propertyToCompare, object valueToCompare, int maxIterations = 10)
{
Type type = typeof(T);
PropertyInfo propertyInfo = type.GetProperty(propertyToCompare);
ICollection response;
do
{
// This is where I want to alter the 'skip' parameter's value so that each iteration observes a different page from the API
response = await getResponse();
maxIterations--;
}
while (maxIterations >= 0 && !response.Any(o => valueToCompare.Equals(propertyInfo.GetValue(o))));
return response.FirstOrDefault(o => valueToCompare.Equals(propertyInfo.GetValue(o)));
}
// Example code that might be in the body of an NUnit test case
var petIdToFind = "123";
var response = RequestHandler.PagedLookupAsync(ApiClient.GetPetsAsync("sparky", take: 50), nameof(PetsApiResonse.Id), petIdToFind);
response.Result.Should().NotBeNull();
response.Result.Id.Should().BeEquivalentTo(petIdToFind);
Как вы уже догадались, цель состоит в том, чтобы проверить, существует ли запись и доступна ли она для поиска. Проблема в том, что поиск не всегда возвращает нужную запись на первой странице результатов, что приводит к ненадежному тестированию. Очевидным путем было бы просто писать циклы в каждом тестовом примере, которому нужна эта функциональность, но я надеюсь, что есть способ централизовать логику.
- Можно отражение можно использовать для доступа к методу, переданному в Func? В моем примере выше, простое изменение параметра «skip» решило бы эту проблему, но, насколько я могу судить, я могу получить доступ только к параметрам Func; а не параметры одного из его параметров.
- Если ответ на вопрос №1 отрицательный, есть ли лучший подход к централизации этой логики, которого я не нашел обдуманный? Дополнительные примечания ниже:
- Методы, выполняющие запросы API, генерируются с использованием спецификации OpenApi. Я считаю, что могу расширить их, но у меня нет прямого доступа для их изменения.
- Я могу гарантировать, что имена параметров всегда одинаковы; т. е. пропустите для начала страницы и возьмите для размера страницы.
Мое решение немного отличается от предложения Марша, но основано на том же подходе. В итоге я полностью отказался от отражения, так как оно больше не нужно:
// RequestHandler.cs
public static async Task PagedLookupAsync(
Func getResponse,
Func lookupFunction,
int maxIterations = 10)
{
int skip = 0;
int take = 20;
ICollection response;
bool isFound = false;
do
{
response = await getResponse(skip, take);
isFound = response.Any(o => lookupFunction(o));
skip += take;
maxIterations--;
}
while (maxIterations >= 0 && !isFound);
return response.FirstOrDefault(o => lookupFunction(o));
}
var response = RequestHandler.PagedLookupAsync((s, t) =>
ApiClient.GetPetsAsync("sparky", skip: s, take: t),
(lookup) => lookup.Id == petIdToFind);
Подробнее здесь: https://stackoverflow.com/questions/784 ... c-in-c-net