Модульное тестирование: как асинхронно возвращать значение из макета интерфейса - PullRequest
0 голосов
/ 25 января 2019

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

Ранее при использовании HttpClient я издевался над HttpMessageHandler и обрабатывал бизнес-логику в методе на другой стороне, однако используемый нами сторонний API требует нескольких вызовов их остальных API с помощью GET-запросов, поэтому я хотел найти решение что сохранило решение более «сухим»

Ниже приведены настройки, которые я сейчас пытаюсь использовать

_requestProvider.Setup(
    svc => svc.GetAsync<PlayerBalance>(It.IsAny<string>(), It.IsAny<string>()))
    .Returns(() => Task.FromResult(new PlayerBalance
    {
        Balance = 0
    }));

_playerService = new PlayerService(_playerRepository.Object, 
            _secretsService.Object,
            _awsConfig,
            _requestProvider.Object);

Мой поступок / утверждение

var result = await _playerService.GetPlayerBalanceAsync(request);

result.Should().BeOfType<PlayerBalance>();

Тестируемый метод

public async Task<PlayerBalance> GetPlayerBalanceAsync(PlayerBalanceRequest playerBalanceRequest)
{
    if (string.IsNullOrEmpty(playerBalanceRequest.Login)) throw new Exception("Login is a required parameter.");


    string url = $@"myrestendpoint";

    var result = await _requestProvider.GetAsync<List<PlayerBalance>>(url);

    return result.FirstOrDefault();
}

И где он проваливает вызов на макете

public async Task<TResult> GetAsync<TResult>(string uri, string token = "")
{
    HttpClient httpClient = CreateHttpClient(token);
    HttpResponseMessage response = await httpClient.GetAsync(uri);

    await HandleResponse(response);
    string serialized = await response.Content.ReadAsStringAsync();

    TResult result = await Task.Run(() =>
            JsonConvert.DeserializeObject<TResult>(serialized, _serializerSettings));

        return result;
}

При работе в режиме «Строгий» он сообщает, что ожидал вызова, но настройки не найдены. Я не совсем уверен, что еще нужно настроить здесь.

результат, возвращаемый из последнего фрагмента кода, всегда равен нулю, но я хочу, чтобы он был PlayerBalance {Balance = 0}

Любая помощь будет оценена.

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

.Returns(Task.FromResult(new PlayerBalance
{
    Balance = 0
}));

.ReturnsAsync(new PlayerBalance {
    Balance = 0
});

1 Ответ

0 голосов
/ 25 января 2019

Вы издеваетесь:

_requestProvider.GetAsync<PlayerBalance>(url)

Когда вы должны насмехаться:

_requestProvider.GetAsync<List<PlayerBalance>>(url)

Настройка макета на ожидаемое поведение:

_requestProvider.Setup(
        svc => svc.GetAsync<List<PlayerBalance>>(It.IsAny<string>(), It.IsAny<string>())
    )
    .ReturnsAsync(() => new List<PlayerBalance>() { new PlayerBalance
    {
        Balance = 0
    }});
...