sia-digital / pibox

PiBox is a service hosting framework that allows .net devs to decorate their services with behaviours or functionality (think of plugins) while only using minimal configuration.
https://sia-digital.gitbook.io/pibox/
MIT License
6 stars 3 forks source link

Add ability to validate ef core model with in memory provider in tests #51

Open fb-smit opened 6 months ago

fb-smit commented 6 months ago

Use case:

To help with making sure the generated model is valid with at least the in-memory provider there should be a method to help out with that.

This does not ensure compatibility with the specific db provider used but as a general check it could be quite useful

Code could look something like this:

public class PersistenceTests
{
    private MyDbContext _myDbContext;

    [SetUp]
    public void SetUp()
    {
        var contextOptions = new DbContextOptionsBuilder<MyDbContext>()
            .UseInMemoryDatabase("test")
            .Options;

        _myDbContext = new MyDbContext(contextOptions);
    }

    [Test]
    public void ValidateEntityRelationships()
    {
        _myDbContext.GetContext().Should().NotBeNull().And.BeOfType<MyDbContext>();
        var entityTypes = _myDbContext.Model.GetEntityTypes();
        foreach (var entityType in entityTypes)
        {
            // We need the class reference to construct the method call
            var reference = typeof(PersistenceTests);

            // We need the name of generic method to call using the class reference
            var methodInfo = reference.GetMethod("AssertFirstOrDefaultIsNull",
                BindingFlags.Instance | BindingFlags.NonPublic);

            // This creates a callable MethodInfo with our generic type
            var miConstructed = methodInfo.MakeGenericMethod(entityType.ClrType);

            // This calls the method with the generic type using Invoke
            miConstructed.Invoke(this, null);
        }
        // stored procedures are not supported by the inMemoryDatabase and thus can't be verified here
    }

#pragma warning disable S1144
#pragma warning disable IDE0051
    /// <summary>
    /// This is called via reflection because of that we need to pragma warning disable the linter
    /// This method is needed since there is not _myDbContext.Set(Type type) method anymore in ef core
    /// </summary>
    /// <typeparam name="T"></typeparam>
    private void AssertFirstOrDefaultIsNull<T>() where T : class
    {
        _myDbContext.Set<T>().FirstOrDefault().Should().BeNull();
    }
#pragma warning restore S1144
#pragma warning restore IDE0051
}