Метод Verify был вызван 4 раза после того, как повторные попытки исчерпаны с помощью MoqC#

Место общения программистов C#
Anonymous
Метод Verify был вызван 4 раза после того, как повторные попытки исчерпаны с помощью Moq

Сообщение Anonymous »

Я занимаюсь рефакторингом кода и создаю модульные тесты. Однако я не могу проверить, что Func вызывался нужное количество раз. Я переименовал и удалил кое-что здесь и там, так как не могу поделиться этим в Интернете.
Логика повтора, имеющая модульные тесты, работает как положено. Теперь я пытаюсь протестировать код, использующий логику повтора.

Код: Выделить всё

public async Task ExecuteWithRetriesAsync(Func action, int maxRetryCount = 3, int delayInSeconds = 5)
{
var attempted = 0;

while (attempted < maxRetryCount)
{
try
{
await action();
return true;
}
catch (DataServiceClientException ex) when (ex.StatusCode == 429)
{
attempted++;
var randomRetryDelay = _delayProvider.Generate(delayInSeconds, 2);
await Task.Delay(TimeSpan.FromSeconds(randomRetryDelay));
delayInSeconds += 5;
}
}
return false;
}
У нас есть следующий код, который использует эту логику повтора в случае исключения.

Код: Выделить всё

public async Task TryDeleteAsync(ToDelete toDelete)
{
try
{
// some logic before we save

await _someClient.SaveChangesAsync();
}
catch (DataServiceClientException ex)
{
var deletedSuccessfully = await _retryHandler.ExecuteWithRetriesAsync(async () => await _someClient.SaveChangesAsync());

if (deletedSuccessfully)
{
return;
}

throw;
}
}
Теперь у меня есть этот тест со всеми необходимыми макетами, но SaveChangesAsyc вызывается только дважды, хотя ожидается 4.

Код: Выделить всё

[Fact]
public async Task TryDeleteAsync_AllRetriesFail_ShouldThrow()
{
var something = MockDataCreator.CreateSomething();
var something2 = MockDataCreator.CreateSomething(something);

_retryHandlerMock
.Setup(x => x.ExecuteWithRetriesAsync(It.IsAny(), 3, 5))
.Callback(async (action, _, _) =>
{
await action();
})
.ReturnsAsync(false); // returns false because all retries failed

_someClientMock
.SetupSequence(x => x.SaveChangesAsync())
.Throws(new DataServiceClientException(429)) // First try fails
.Throws(new DataServiceClientException(429)) // Second try fails
.Throws(new DataServiceClientException(429)) // Third try fails
.Throws(new DataServiceClientException(429)); // Fourth try fails

await Assert.ThrowsAsync(
async () => await _sut.TryDeleteAsync(something2));
_someClientMock.Verify(x => x.SaveChangesAsync(), Times.Exactly(4)); // Assertion fails because it's only called twice
_retryHandlerMock.Verify(x => x.ExecuteWithRetriesAsync(It.IsAny(), 3, 5), Times.Once);
}
Кто знает, что сделать, чтобы проверить это в юнит-тестах? Потому что реальный код, кажется, работает....

Подробнее здесь: https://stackoverflow.com/questions/788 ... d-with-moq

Вернуться в «C#»