繁体   English   中英

您如何使用Moles来阻止EntityFramework 4.1中的数据库查询DbContext?

[英]How do you use Moles to mole DbContext from querying the database in EntityFramework 4.1?

我正在使用Entity Framework 4.1进行数据库访问,并希望对以下代码进行单元测试:

// Get all the entities including children
using (MyContext context = new MyContext())
{
    return context.EmployeeProfiles.Include("EmployeeProperties").ToList();
}

我正在使用Moles来消除数据库依赖性,但是我被卡住了。 我应该开始消除实体框架中的哪一点。

我一直在关注此示例,但它适用于LINQ-To-SQL。

我还考虑调试/跟踪Entity Framework,以找出对数据库进行调用之前要拦截的函数。 但是,似乎没有可用于跟踪Entity Framework 4.1的源代码。 讨论

谁能指导我在DbContext中淘汰哪些功能,以便可以获取EmployeeProfiles的列表?

这是完全可能的,而且我认为这是有效的。 是的,您可以使用存储库模式并模拟您的存储库,通常这样就足够了。

但是,我在嘲笑EF时看到了两个参数:

  1. EF已经是实际数据库的抽象/存储库,无需在其周围编写另一个存储库。
  2. 您通过EF编写的任何存储库都是您的代码 因此,您应该测试它,迟早要添加需要涵盖的逻辑。

在这一点上这是一场神圣的战争,但是有一些论点支持您的工作。

因此,要使用Moles进​​行此操作,您需要做两件事。 首先,更改创建DbContext的模板,以使所有表的返回类型为IDbSet<>而不是DbSet<>

然后,在测试项目中,为IDbSet添加一个测试类实现。 我发现很好用。

现在,在测试中,您可以执行以下操作:

List<EmployeeProfile> testProfiles = /*your test data here*/;
MMyContext.AllInstances.EmployeeProfilesGet  = (instance) => 
{
    return new InMemoryDbSet<EmployeeProfile>(testProfiles);
};


// Get all the entities including children
using (MyContext context = new MyContext())
{
    return context.EmployeeProfiles.Include("EmployeeProperties").ToList();
}

它快速,简单,并且允许您测试代码直到离开控件为止。

在我看来,您不是在通过存储库模式消除对EF的依赖,而是在尝试模拟EF的特定行为。 我看不出这样做的意义,这将非常困难,EF并非要被嘲笑。

您的存储库大概是这样的:

public interface IRepository
{
      IEnumerable<EmployeeProfiles> EmployeeProfiles { get; }
}

public class Repository
{
    public IEnumerable<EmployeeProfiles> EmployeeProfiles
    {
        get
        {
            // Get all the entities including children     
            using (MyContext context = new MyContext())     
            {
                return context.EmployeeProfiles.Include("EmployeeProperties").ToList();     
            }
        }
    }
}

这样,您就删除了关于如何返回EmployeeProfiles的存储库依赖性。 现在,您可以嘲笑自己内心的内容(尚未使用过Moles),但是使用Moq,您可以执行以下操作:

public void TestEmptyList()
{
    var mock = new Mock<IRepository>();
    var expected = new List<EmployeeProfiles>();
    mock.SetupGet(ep => ep.EmployeeProfiles).Returns(expected);

    var actual = mock.Object.EmployeeProfiles;

    Assert.AreEqual(expected, actual);
}

因此,如果将要从数据库中抽象出来的方法/属性放到存储库接口中,则可以模拟出要测试其可能返回的所有值。

不确定您是否正在执行此操作,我不确定。 我不明白您为什么要对EF进行单元测试,您希望获得什么? 这将是非常困难的,它并非旨在被嘲笑(很少有接口/虚拟)。 您返回的数据的任何模拟(实际上就是您真正感兴趣的所有事情)都可以按照上述方法进行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM