I have implemented custom retry strategy on an API which is in .NET Core 2.2. Retry strategy should work only for transient errors from the database(Azure SQL). How can I generate transient errors, to test this feature?
I don't know your code, but this is one solution. The idea is to separate the retry logic from the actual action that needs to be retried, so that each can be tested.
A static RetryHandler could also work, but it depends on your need.
Psedo code, does not compile.
public RetryHandler : IRetryHandler
{
private static List<Type> transientErros = new List<Type>
{
typeof(TimeoutException),
typeof(SomeotherExceptionThatRequiresRetry),
}
public void RetryOnTransientError(Action action, int attempts = 3)
{
for (var i = 0; i < attempts; i++)
{
try
{
action();
return;
}
catch(Exception e)
{
if(transientErros.Contains(e.GetType())
continue;
throw;
}
}
}
}
public class UserRepository
{
private IMyDbContext context;
private IRetryHandler retryHandler;
public Repository(IMyDbContext context, IRetryHandler retryHandler)
{
this.context = context;
this.retryHandler = retryHandler;
}
public void InsertUser(User user)
{
retryHandler.RetryOnTransientError(() => DoInsertUser(user));
}
private void DoInsertUser(User user)
{
// insert logic
context.SaveChanges();
}
}
[Test]
public void InsertUserRetriesOnTransientError()
{
// Arrange
var contextMock = new Mock<IMyDbContext>();
var repository = new Repository(contextMock);
var user = CreateUser();
contextMock.Setup(x => x.SaveChanges()).Throws<TransientException>());
// Act
Assert.Throws<TransientException>(() => repository.InsertUser(user));
// Assert
// verify SaveChanges() was called 3 times
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With