The following test that was working with EF 4.2 now throws the next exception with EF 4.3
System.ArgumentException : Type to mock must be an interface or an abstract or non-sealed class. ----> System.TypeLoadException : Method 'CallValidateEntity' on type 'Castle.Proxies.DbContext43Proxy' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is overriding a method that is not visible from that assembly.
[Test] public void CanCreateMoqTest() { // Arrange Mock<DbContext43> mock; // Act mock = new Mock<DbContext43>(); // Assert Assert.NotNull(mock.Object); } public class DbContext43:DbContext { }
What should I do? Create an interface for my DbContext43?
Is this a breaking change between 4.2 and 4.3?
Thanks!!
Thanks for finding this. The problem is caused by the the InternalsVisibleTo attributes that we stripped out of the EF 4.2 release but left in for the EF 4.3. This allowed Moq (which we use for our tests) to see the internals of EntityFramework.dll. However, since your assembly cannot see those internals you ended up with the exception.
We plan to do a patch release of EF 4.3 in the next few weeks and will be stripping InternalsVisibleTo out of this release after which mocking should work again.
Update: This is now fixed in EF 4.3.1 (and EF 5.0-beta1) released today. Update your NuGet package to get the fix. See http://blogs.msdn.com/b/adonet/archive/2012/02/29/ef4-3-1-and-ef5-beta-1-available-on-nuget.aspx for details.
This kind of exception usually indicates member you're trying to override is not exposed as part of public interface in the given assembly (or perhaps to be more precise - overriding assembly does not see it). And if we take a look at CallValidateEntity
implementation in EntityFramework 4.3:
internal virtual DbEntityValidationResult CallValidateEntity( DbEntityEntry entityEntry, IDictionary<object, object> items) { return this.ValidateEntity(entityEntry, items); }
We indeed notice that this method is internal
, and as a result falls in the non-overridable category (non-overridable considering no InternalsVisibleTo
attribute is used). This is naturally matched by proper metadata entry:
Method #20 (06000a03) ------------------------------------------------------- MethodName: CallValidateEntity (06000A03) Flags : [Assem] [Virtual] [HideBySig] [NewSlot] (000003c3)
It's rather unclear why Moq attempts to override that member... considering it shouldn't see it in first place.
Wrapping your context in an interface and exposing only methods you actually use is a viable option - it should be enough to get your test passing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With