【问题标题】:How to test queries with Entity Framework Core and Linq?如何使用 Entity Framework Core 和 Linq 测试查询?
【发布时间】:2021-10-08 01:22:51
【问题描述】:

我的 .NET Core 解决方案结构清晰。在持久性项目中,我有我的存储库。在实现中,我使用 Linq 对数据库进行了一些调用。

public class QualitativeResearchRepository 
       : BaseRepository<QualitativeResearch>, IQualitativeResearchRepository
{
    public QualitativeResearchRepository(PSCContext db,
           ILogger<QualitativeResearchRepository> log) 
           : base(db, log)
    {
    }

    public decimal GetAverageForClarity(
          Expression<Func<QualitativeResearch, bool>> func)
    {
        var list = _db.QualitativeResearches.Select(r => r.Clarity)
                      .DefaultIfEmpty();

        if (list == null || list.Count() == 0)
            return 0;

        var result = list.Average();

        return result == null ? 0 : (decimal)result;
    }
}

所以,有些函数我想应用过滤器和/或聚合,然后进行一些计算。我想模拟上下文(在代码PSCContext 中),这样我就可以测试过滤器和聚合是否如我预期的那样正确。在Microsoft Documentation 上有示例,但仅用于添加新记录。

【问题讨论】:

  • 只是为了确认 - 这是 EF Core,对吗?您已标记此 EF Core,但您链接的文档适用于 EF 6 (.NET Framework)。
  • 是的,它是 EF Core。 .NET Framework 的 MSDocsis 但Mock 部分可能相同。
  • InMemory 提供者?
  • 查看有关不同方法的文档,例如 inmemorysqllite mock docs.microsoft.com/en-us/ef/core/testing

标签: c# unit-testing entity-framework-core nunit


【解决方案1】:

对于 Entity Framework Core,Microsoft 建议使用内存提供程序进行单元测试。与尝试解开 EF 的 DbContext 的内部结构相比,它在运行时同样快速且简单得多。欲了解更多关于为什么这不好的信息,see their explanation

我们使用测试替身对 EF Core 进行内部测试。但是,我们从不尝试模拟 DbContext 或 IQueryable。这样做是困难的、麻烦的和脆弱的。 不要这样做。

对于初学者,您需要安装 EF Core In Memory 提供程序。

dotnet 添加包 Microsoft.EntityFrameworkCore.InMemory

从那里,您可以使用 DbContextOptions&lt;T&gt; 构造函数简单地构造您的 DbContext。

using Microsoft.EntityFrameworkCore.InMemory

// Further down...

public void GivenAnyFilter_WhenNoRecordsAreFound_ThenReturnsZero()
{
    var dbContextOptions = new DbContextOptionsBuilder<PSCContext>()
        .UseInMemoryDatabase("InMemoryDatabase")
        .Options;

    var dbContext = new PSCContext(dbContextOptions);

    // Setup your test and invoke...
}

【讨论】:

  • .UseInMemoryDatabase() 你必须指定一个数据库名称。所以,这条线是var dbContextOptions = new DbContextOptionsBuilder&lt;PSCContext&gt;().UseInMemoryDatabase("FakeDb").Options;。谢谢
  • 已编辑!抱歉,这是我的想法。
  • 好吧,事实上他们不推荐使用内存提供程序进行测试:docs.microsoft.com/en-gb/ef/core/providers/in-memory/…
  • 当然——集成测试会失败。但是,在单元测试上下文中,它是完美的,因为数据库本身不是问题。这就是 OP 试图测试的。从上面的链接->“在测试 EF Core 内部时,这些都不是很重要,因为我们专门在数据库与测试无关的情况下使用它。”
  • 当问题是“如何使用 Entity Framework Core 和 Linq 测试 查询?” 时,数据库如何不成为问题?使用内存提供程序进行测试 - LINQ to Objects?查询处理管道中的许多东西是不同的,因此测试是无用的。并且不要过于依赖官方链接,事实上他们(EFC 团队)正在考虑让内存提供程序退役。 SQLite in-memory database比较好,但还是和真实的数据库(比如SqlServer等)有区别
猜你喜欢
  • 2017-03-19
  • 1970-01-01
  • 2021-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-25
  • 2020-09-11
相关资源
最近更新 更多