DbContext.Set <tentity>()在测试框架中返回垃圾数据代理</tentity>

时间:2015-04-09 12:59:00

标签: c# entity-framework entity-framework-6

在我的测试框架中,当我调用DbContext.Set<FakeClass1>()时,我正在返回一大堆垃圾数据(它似乎是代理,因为它们是System.Data.Entity.Dynamicproxies)。如果我打电话给DbContext.FakeClass1s,我就不会得到任何这些垃圾。

问题是,在一个通用的Repository bass类中,我调用了DbContext.Set<TEntity>(),因为显然使用它来减少代码是一件好事。但我需要为我的测试框架解决这个问题。

这是测试代码 - 结果应该是2的计数,因为只有两个被添加到DbContext DbSet。

[TestMethod]
    public void FindAll_Should_Work()
    {
        // Arrange
        var dbContext = new FakeDbContext();

        // Act
        var s1= dbContext.FakeClass1s;
        var s2 = dbContext.Set<FakeClass1>();

        // Assert
        Assert.AreEqual(2, s1.Count());
        Assert.AreEqual(2, s2.Count());
    }

s1的结果是正确的。但是对于s2,结果是14。

以下是FakeDbContext的代码:

public class FakeDbContext : System.Data.Entity.DbContext
{
    public DbSet<FakeClass1> FakeClass1s { get; set; }
    public DbSet<FakeClass2> FakeClass2s { get; set; }

    public FakeDbContext()
    {
        PopulateData();
    }

    private void PopulateData()
    {
        var f11 = new FakeClass1()
        {
            ID = 1,
            Name = "One"
        };
        var f12 = new FakeClass1()
        {
            ID = 2,
            Name = "Two"
        };            
        FakeClass1s.Add(f11);
        FakeClass1s.Add(f12);
    }
}

此外,这些额外的结果实际上是在其他测试运行期间累积的数据。在那里,我发现具有来自其他测试的值的对象。即使我单独运行此测试,也会获得这种情况,并注释掉使用和测试这些其他对象的代码。所以有些东西被记住了。

此外,查看该本地窗口似乎s1实际上是DbSet<FakeClass1>,其中s2是查询(?):

enter image description here

编辑:标记了正确答案,但想在此处注意:问题是继承自System.Data.Entity.DbContext。显然,要做的只是实现接口而不是从这个类派生,正如andrerpena友好建议的那样。一旦我停止从System.Data.Entity.DbContext继承,奇怪的行为就消失了。

1 个答案:

答案 0 :(得分:1)

您所谓的垃圾是您在PopulateData中创建的实体,并且以某种方式在数据库中保留了这些实体。这些dynamicProxies是从FakeClass1FakeClass2继承的动态类型的对象。 EF创建代理的原因是您可以从延迟加载和适当的属性同步中受益。

您的FakeDbContext继承自真实DbContext。这导致实体实际上被持久化并从商店中检索(你必须调用SaveChanges以便它可以发生,但你可能正在这样做或过去做过)。这不是一个好习惯。

人们通常做的是创建一个IDbContext界面,然后专门为您的上下文创建另一个界面。类似于IYourAppContext