entity-framework - 模拟 Entity Framework 内连接

标签 entity-framework mocking moq

我需要从数据访问层对内部联接方法进行单元测试。

我的 DAL 看起来像这样:

public class MyDAL:IMyDAL
{
    private MyContext context;

public MyDAL(MyContext Context)
    {
        this.context = Context;
    }
public IEnumerable <Parent> Read(int childId)
    {
        var query = from parent in context.Parent
                    join child in context.Child on parent.Id equals child.Id
                    where child.Id == childId
                    select env;
        return query.ToList();
    }

我想通过模拟 Entity Framework 来对 Read 方法进行单元测试,请点击此链接 http://msdn.microsoft.com/en-us/data/dn314429.aspx .

  [TestMethod]
    public void ReadMethod()
    {

        var data = new List<Parent> 
        { 
            new Parent { Id = 20 },
        }.AsQueryable();
        var data2 = new List<Child> 
        { 
            new Child { Id = 8 },
        }.AsQueryable();


        var mockSetPar = new Mock<DbSet<Parent>>();
        var mockSetChild = new Mock<DbSet<Child>>();

        mockSetPar.As<IQueryable<Parent>>().Setup(m => m.Provider).Returns(data.Provider);
        mockSetPar.As<IQueryable<Parent>>().Setup(m => m.Expression).Returns(data.Expression);
        mockSetPar.As<IQueryable<Parent>>().Setup(m => m.ElementType).Returns(data.ElementType);
        mockSetPar.As<IQueryable<Parent>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());

        moockSetChild.As<IQueryable<Child>>().Setup(m => m.Provider).Returns(data2.Provider);
        mockSetChild.As<IQueryable<Child>>().Setup(m => m.Expression).Returns(data2.Expression);
        mockSetChild.As<IQueryable<Child>>().Setup(m => m.ElementType).Returns(data2.ElementType);
        mockSetChild.As<IQueryable<Child>>().Setup(m => m.GetEnumerator()).Returns(data2.GetEnumerator());


        var customDbContextMock = new Mock<MyContext>();
        customDbContextMock.Setup(x => x.Parent).Returns(mockSetPar.Object);
        customDbContextMock.Setup(x => x.Child).Returns(mockSetChild.Object);




        var myDAL = new MyDAL(customDbContextMock.Object);


        var actual = myDAL.Read(8);
          Assert.IsNotNull(actual);

实际结果为空,因为 join 方法尚未被模拟,因此它不会返回任何内容。

如何模拟 join 方法以返回值?

谢谢

最佳答案

数据库交互的内存中测试可能会产生误导,因为 LINQ to Entities 功能是 LINQ to Objects 功能的子集,因此您可以编写一个绿色测试,但查询在生产中总是会抛出异常。

这在概念层面上也是错误的。 DAL 是位于两个系统(app 和 db)边界上的代码。它的责任是将它们整合起来。因此,如果您隔离这些集成组件,您的测试就变得毫无意义,因为它模拟了 SUT 的核心职责。

要测试查询逻辑,您必须使用行为类似于生产数据库提供程序的数据库提供程序。所以你需要集成测试。 = 一个有用的解决方案是使用 SQLite 内存数据库。在 Entity Framework 涵盖的大多数场景中,它的行为就像真正的数据库,但在单元测试中的执行速度几乎与基于内存集合的模拟一样快。

如果您愿意,您可以将 SQLite 视为类固醇数据库模拟。

关于entity-framework - 模拟 Entity Framework 内连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22660676/

相关文章:

c# - 预期对模拟调用一次,但调用了 2 次 : m => m. SaveChanges() , UnitTest

java - 在 Java 类中进行模拟

unit-testing - 方法设置中的 Moq 匹配和验证数组/IEnumerable 参数

c# - 将 MySql 与 ASP.NET MVC 结合使用( Entity Framework 6)

oracle - ORA-01031 : insufficient privileges with Oracle view using Entity Framework

c# - 如何在 EF Core 多对多关系中对删除进行建模?

java - 如何在java中模拟局部变量?

c# - 如何模拟返回的模拟对象的方法?

C# Static Readonly log4net 记录器,有什么方法可以在单元测试中更改记录器?

c# - EntityFramework 6 现有数据库和新数据库的迁移?