Mocking MySqlException

As pleased as I am about Entity Framework Core’s InMemoryDatabase for testing, some failures cannot be easily simulated because InMemory doesn’t enforce database integrity, like constraint validation.

One of my operations uses foreign key constraints to validate data on insert and I wanted to mock this functionality to ensure a correct return value. This proved a little challenging because the type which triggers the failure, MySqlException, has no public constructors. Therefore a little reflection magic was required:

using System.Reflection;

public class MockSaveChangesAsyncSqlContext : SqlContext
{
    public MockSaveChangesAsyncSqlContext() { }
    public MockSaveChangesAsyncSqlContext(DbContextOptions<SqlContext> options) : base(options) { }

    public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken))
    {
        var mySqlExceptionType = typeof(MySql.Data.MySqlClient.MySqlException).GetTypeInfo();
        var internalConstructor = (from consInfo in mySqlExceptionType.DeclaredConstructors
                                    let paramInfos = consInfo.GetParameters()
                                    where paramInfos.Length == 1 && paramInfos[0].ParameterType == typeof(string)
                                    select consInfo).Single();

        var innerException = internalConstructor.Invoke(new[] { "foreign key constraint fails" }) as Exception;
        throw new Exception("", innerException);
    }
}

It is important to note this is testing code. I would absolutely advise against using reflection to dig out hidden constructors in application code for many reasons, not the least of which is that a change to the library could suddenly break your application!