在EntityFramework 4.1中,如何使用mole将DbContext从查询数据库中移除

本文关键字:查询 DbContext 数据库 何使用 EntityFramework mole | 更新日期: 2023-09-27 18:07:40

我使用实体框架4.1数据库访问,并希望单元测试以下代码:

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

我正在使用鼹鼠鼹鼠的数据库依赖,但我卡住了。我应该从实体框架的哪一点开始计算

我遵循这个例子,但它是LINQ-To-SQL。

我还在考虑调试/跟踪实体框架,以找出在调用数据库之前拦截哪个函数。然而,似乎没有实体框架4.1可用的源代码来跟踪。看到讨论。

谁能指导我哪些功能(s)我应该在DbContext中moling出来,这样我就可以得到EmployeeProfiles的列表回来?

在EntityFramework 4.1中,如何使用mole将DbContext从查询数据库中移除

在我看来,不是通过Repository模式移除对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返回方式的存储库依赖。现在你可以随心所欲地模仿了(还没有使用过mole),但是使用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进行单元测试,您希望获得什么?这将是非常困难的,它不是为模拟而设计的(很少有接口/虚拟)。对返回的数据的任何模拟(这是您真正感兴趣的)都可以按照上面的方法完成。

这是完全可能的,而且在我看来是有效的。是的,您可以使用存储库模式并模拟您的存储库,这通常已经足够好了。

然而,我看到的两个参数用来嘲弄EF:

  1. EF已经是实际数据库之上的一个抽象/存储库,围绕它编写另一个存储库是没有必要的。你在EF上写的任何存储库都是你的代码。因此,您应该对其进行测试,因为您迟早会添加需要覆盖的逻辑。

在这一点上,这有点像一场圣战,但也有一些观点支持你的做法。

所以,要对mol做这个,你需要做两件事。首先,更改创建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();
}

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