Ef6: Can no longer mock DbContext in EF 6.3 Preview.

Created on 9 Jul 2019  ·  13Comments  ·  Source: dotnet/ef6

Previously I was able to mock my DbContext for testing purposes using Moq like so:

var mock = new Mock<MyDbContext>();
var service = new MyService(mock.Object);

Ever since upgrading to EF 6.3 Preview 6 now this code throws the following exception

System.ArgumentException
  HResult=0x80070057
  Message=Type to mock must be an interface or an abstract or non-sealed class. 
  Source=Moq
  StackTrace:
   at Moq.CastleProxyFactory.CreateProxy(Type mockType, IInterceptor interceptor, Type[] interfaces, Object[] arguments)
   at Moq.Mock`1.InitializeInstance()
   at Moq.Mock`1.OnGetObject()
   at Moq.Mock.get_Object()
   at Moq.Mock`1.get_Object()
   at Ancestry.Rosetta.UnitTests.Services.CultureServiceTests.InitializeService() in C:\Projects\rosetta-core\Ancestry.Rosetta.UnitTests\Services\TestsOf_CultureService.cs:line 95

Inner Exception 1:
TypeLoadException: Method 'InitializeLazyInternalContext' on type 'Castle.Proxies.RosettaEntitiesProxy' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is overriding a method that is not visible from that assembly.

I found an old question on StackOverflow where a similar error was occurring during the upgrade from EF 4.2 to EF 4.3. If I understand the post correctly, InternalsVisibleTo attributes were not being properly stripped out causing Moq to fail:
https://stackoverflow.com/a/9266279/311444

Could something similar to this be happening in EF 6.3?

Steps to reproduce

Trying to instantiate an Object of a mocked DbContext throws an exception.

c# var mock = new Mock<MyDbContext>(); var service = new MyService(mock.Object);

Further technical details

EF version: 6.3.0-preview6-19304-03
Moq version: 4.12.0
Operating system: Windows 10
IDE: Visual Studio 2017 15.9.13 and Visual Studio 2019 16.2.0 Preview 3.0

closed-fixed type-bug

All 13 comments

Also experiencing this issue

Looks like 2,234 (74 functional; 16%) of our tests fail without [InternalsVisibleTo("DynamicProxyGenAssembly2")]

@ajcvickers We should discuss what we want to do here. This was regressed when we moved the build to Arcade.

@bricelam So am I correct in saying is that Arcade doesn't have a mechanism to strip InternalsVisibleTo from the build, but:

  • If we always generate builds without InternalsVisibleTo, then our tests fail
  • If we always generate a build with InternalsVisibleTo, then it's a breaking change to our customers

Is that correct?

Correct, we could...

  • Skip the failing tests
  • Customize our build to test against a version with InternalsVisibleTo but produce a package using a version without it (build twice)
  • Ship with the regression

@bricelam How feasible is the second option?

It should be as easy as creating a second csproj--referencing one in the tests and the other in the NuGet package.

There may also be other ways to re-use the same project and re-build it after running the tests, but two projects would be the simplest solution

Okay, simple is good. Let's go with that.

@bricelam in case you haven’t seen it, this PR contains some relevant details, including an “unofficial feature” to generate InternalsVisibleTo in Arcade: https://github.com/dotnet/sdk/pull/3439.

Thanks everyone for looking into this. Just to confirm, I'm assuming a fix for this was NOT included in the incremental Entity Framework 6.3 Preview 7 that was released yesterday.

@Pinski Correct.

Just had the same issue testing 6.3 Preview 8, unfortunately the fix is not in there. Will there be a Preview 9 @ajcvickers ?

@davidroth Looks like it just missed preview 8. Should be in the daily builds and preview 9.

Was this page helpful?
0 / 5 - 0 ratings