rgvlee/EntityFrameworkCore.Testing

Unable to dispose mocked DB context

Closed this issue · 3 comments

I have a method, that creates CreateDbContextFromFactory in using block as recommended in https://docs.microsoft.com/en-us/ef/core/dbcontext-configuration/#using-a-dbcontext-factory-eg-for-blazor

public void DoSomething()
{
    using (var context = _contextFactory.CreateDbContext())
    {
        // ...
    }
}

Notice that the DbContext instances created in this way are not managed by the application's service provider and therefore must be disposed by the application.

However it causes exception when I am using Create.MockedDbContextFor for NSubstitute

System.NotSupportedException
  HResult=0x80131515
  Message=Cannot dynamically create an instance of System.Void.
  Source=System.Private.CoreLib
  StackTrace:
   at System.RuntimeType.CreateInstanceCheckThis()
   at System.RuntimeType.ActivatorCache..ctor(RuntimeType rt)
   at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean wrapExceptions)
   at System.Activator.CreateInstance(Type type, Boolean nonPublic, Boolean wrapExceptions)
   at System.Activator.CreateInstance(Type type)
   at rgvlee.Core.Common.Extensions.TypeExtensions.GetDefaultValue(Type type)
   at EntityFrameworkCore.Testing.NSubstitute.Helpers.NoSetUpHandler`1.Handle(ICall call)
   at NSubstitute.Routing.Handlers.ReturnFromCustomHandlers.Handle(ICall call)
   at NSubstitute.Routing.Route.Handle(ICall call)
   at NSubstitute.Core.CallRouter.Route(ICall call)
   at NSubstitute.Proxies.CastleDynamicProxy.CastleForwardingInterceptor.Intercept(IInvocation invocation)
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at NSubstitute.Proxies.CastleDynamicProxy.ProxyIdInterceptor.Intercept(IInvocation invocation)
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at Castle.Proxies.MyDbContextProxy.Dispose()
   at UnitTests.CommandLineRunnerTests.MockDbContext_Dispose() 

The minimal test that fails is

 ```

[TestMethod]
public void MockDbContext_Dispose()
{
var dbContextFactory = new MyDbMockContextFactory();
using (var dbContext = dbContextFactory.CreateDbContext())
{
} //is Dispose successful ?
}

        public class MyDbMockContextFactory : IDbContextFactory<MyDbContext>
        {
            public MyDbContext CreateDbContext()
            {
                var mockedDbContext = Create.MockedDbContextFor<MyDbContext>();
                //Add using EntityFrameworkCore.Testing.NSubstitute.Extensions;
                mockedDbContext.AddExecuteSqlInterpolatedResult(11);//pass SQL to get different results
                return mockedDbContext;
            }
          
    }

I've been able to reproduce the issue, it looks like it affects all of the void methods in the NSub implementation. The Moq implementation appears unaffected.

I've raised #122 and released 4.0.2-rc01. Please test and let me know if it solves your issue. I'll release 4.0.2 once I've rolled the change through versions 1.x, 2.x, and 3.x.

Thanks, Install-Package EntityFrameworkCore.Testing.NSubstitute -Version 4.0.2-rc01
works correctly

Version 4.0.2 has been released.