你如何使用Moles来诋毁DbContext来查询EntityFramework 4.1中的数据库?

时间:2011-09-02 21:52:29

标签: c# mocking moles pex pex-and-moles

2 个答案:

答案 0 :(得分:0)

在我看来,不是通过存储库模式删除对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进行单元测试,你希望获得什么?这将是非常困难的,它不是被设计为嘲笑(非常少的接口/虚拟)。你返回的任何数据的嘲笑,实际上你真正感兴趣的都是如上所述。

答案 1 :(得分:0)

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

然而,我见过两个嘲笑EF的论点:

  1. EF已经是实际数据库的抽象/存储库,没有必要在其周围编写另一个存储库。
  2. 您通过EF撰写的任何存储库都是您的代码。因此,您应该对其进行测试,因为您最终将最终添加需要覆盖的逻辑。
  3. 在这一点上,这是一场神圣的战争,但有些论据支持你正在做的事情。

    所以,要与Moles一起做这件事,你需要做两件事。首先,更改创建DbContext的模板,以便所有表的返回类型为IDbSet<>而不是DbSet<>

    然后,在您的测试项目中,为IDbSet添加一个测试类实现。我发现this one能够很好地运作。

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

    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();
    }
    

    它快速,简单,并且允许您测试代码,直到它让您无法控制。