0

Main Goal : Automatic Moq an entire DBContext
Current Problem: Setup don´t work.
It runs and adds the Setup but when you try to access the Data you get an "NotImplemented Exception"

The member 'IQueryable.Provider' has not been implemented on type 'DbSet 1Proxy_4' which inherits from 'DbSet 1'. Test doubles for 'DbSet 1' must provide implementations of methods and properties that are used.

My class

 public abstract class MoqBase<T> where T : DbContext
{
    public Mock<T> MockContext { get; private set; }
   
    public void Mock()
    {
        MockContext = new Mock<T> { DefaultValue = DefaultValue.Mock };
        MockContext.SetupAllProperties();
        PrepareContext();
    }

    private void PrepareContext()
    {
        var propertyList = MockContext.Object.GetType().GetProperties();
        var tablePropertyList = propertyList.Where(x => x.PropertyType.FullName.Contains("DbSet")).ToList();
        foreach (var tableProperty in tablePropertyList)
        {
            var proxy = tableProperty.GetValue(MockContext.Object);
            dynamic mockSet = ((dynamic)proxy).Mock;
            AddTableSetup(mockSet);
        }
    }

    public void AddTableSetup<TTable>(Mock<DbSet<TTable>> Mockset) where TTable : class
    {
        var list = new List<TTable>();
        var data = list.AsQueryable();
        Mockset.As<IQueryable<TTable>>().Setup(m => m.Provider).Returns(data.Provider);
        Mockset.As<IQueryable<TTable>>().Setup(m => m.Expression).Returns(data.Expression);
        Mockset.As<IQueryable<TTable>>().Setup(m => m.ElementType).Returns(data.ElementType);
        Mockset.As<IQueryable<TTable>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator);
    }
}

TestMoq which implements MoqBase

public class TestMoq : MoqBase<NetConPortalContext>//NetConPortalContext is my dbContext
{
    public TestMoq() => Mock();
}

Try to access

  static void Main()
    {
        var moq = new TestMoq();
        var context = moq.MockContext.Object;
        var test = context.User.FirstOrDefault();
    }

Picture of Error and Setup in Debug

VDA
  • 1
  • 1
  • 1
  • Small question (just for me) - what is the point of mocking db context? – Guru Stron Apr 27 '22 at 10:58
  • You might want to see [Mocking classes that implement IQueryable with Moq](https://stackoverflow.com/questions/7048511/mocking-classes-that-implement-iqueryable-with-moq) – JonasH Apr 27 '22 at 11:54
  • @GuruStron if you want to test a Method or Class you only have to change the DBContext. If i only mocked one Table i would have to write a setup for each new Table. – VDA Apr 27 '22 at 12:01
  • @VDA why not use inmemory database context? – Guru Stron Apr 27 '22 at 12:01
  • 1
    @GuruStron Never heard from it. It seems to only work with EF Core, i forgot to add that i use EF not EF Core. But i will look into it for my other Projects. – VDA Apr 27 '22 at 12:18

0 Answers0