Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate transient errors for testing

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?

like image 589
Vikas Avatar asked Mar 19 '26 05:03

Vikas


1 Answers

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
}
like image 54
Michael Avatar answered Mar 21 '26 05:03

Michael



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!