实体框架4.3和Moq无法创建DbContext模拟

时间:2012-02-12 00:40:37

标签: c# entity-framework testing moq

以下使用EF 4.2的测试现在抛出EF 4.3的下一个异常

  

System.ArgumentException:类型为mock必须是接口或   抽象或非密封的课程。 ----> System.TypeLoadException:   'Castle.Proxies.DbContext43Proxy'类型的方法'CallValidateEntity'   来自程序集'DynamicProxyGenAssembly2,Version = 0.0.0.0,   Culture = neutral,PublicKeyToken = null'覆盖了一个方法   从那个集会看不到。

[Test]
public void CanCreateMoqTest()
{
    // Arrange
    Mock<DbContext43> mock;

    // Act
    mock = new Mock<DbContext43>();

    // Assert
    Assert.NotNull(mock.Object);
}

public class DbContext43:DbContext
{
}

我该怎么办?为我的DbContext43创建一个界面?

这是4.2和4.3之间的重大变化吗?

谢谢!

2 个答案:

答案 0 :(得分:38)

感谢您找到这个。问题是由我们从EF 4.2版本中删除但留给EF 4.3的InternalsVisibleTo属性引起的。这允许Moq(我们用于测试)查看EntityFramework.dll的内部。但是,由于您的程序集无法看到这些内部结构,因此您最终会遇到异常。

我们计划在接下来的几周内发布EF 4.3的补丁版本,并将剥离此版本中的InternalsVisibleTo,然后再进行模拟。

更新:现在已在今天发布的EF 4.3.1(和EF 5.0-beta1)中修复。更新您的NuGet包以获得修复。有关详细信息,请参阅http://blogs.msdn.com/b/adonet/archive/2012/02/29/ef4-3-1-and-ef5-beta-1-available-on-nuget.aspx

答案 1 :(得分:5)

这种异常通常表示您尝试覆盖的成员未作为给定程序集中公共接口的一部分公开(或者更准确地说 - 覆盖程序集看不到它) 。如果我们take a lookCallValidateEntity实施EntityFramework 4.3:

internal virtual DbEntityValidationResult CallValidateEntity(
    DbEntityEntry entityEntry, IDictionary<object, object> items)
{
    return this.ValidateEntity(entityEntry, items);
}

我们确实注意到这个方法是internal,结果属于不可覆盖的类别(不可覆盖的,因为没有使用InternalsVisibleTo属性)。这通过适当的元数据输入自然匹配:

Method #20 (06000a03)
-------------------------------------------------------
  MethodName: CallValidateEntity (06000A03)
  Flags     : [Assem] [Virtual] [HideBySig] [NewSlot]  (000003c3)

目前还不清楚为什么Moq试图覆盖该成员......考虑到它不应该首先看到它。

在界面中包装你的上下文并仅暴露你实际使用的方法是一个可行的选择 - 它应该足以让你的测试通过。