如何将Entity Framework Core数据库作为InMemory数据库进行测试,并对大量的行进行插入功能。

问题描述 投票:2回答:1

在我们的一个项目中,我们有一个有很多表和数千行的数据库。对于我们的集成测试,我们希望我们的测试是针对一个固定的数据库状态运行的,例如,5000行,这样测试是确定性的,总是返回相同的结果。

我们之前曾使用过一个小型的Entity Framework Core InMemoryDatabases,其中我们添加了像这样的20行。

private DbContextOptions<OurDataContext> GetInMemoryDbContextOptions()
{
    var options = new DbContextOptionsBuilder<OurDataContext>()
        .UseInMemoryDatabase(databaseName: "foo")
        .Options;

    using (var context = new OurDataContext(options))
    {
        context.OurTable.Add(new OurTable(){...});
        // ...
        context.SaveChanges();
    }
    return options;
}

然而,在我们的新案例中,这是不可行的 这么多的行,应该从生产数据库中提取。我们需要一个很好的方法将真实的数据同步到我们的内存数据库中。如何才能做到这一点呢?

理想情况下,我们会用SQL Management Studio将生产数据库的相关部分导出到一个SQL脚本中,并在Git中跟踪这个SQL导出,作为我们测试代码的一部分。就我们所见,目前还没有任何的 从SQL脚本导入数据 由于我们无法对其运行SQL脚本。

https:/docs.microsoft.comen-usefcoremiscellaneoustesting。 总结了这些可用的选项,但我还是不知道我们的解决方案是怎样的,因为我们需要的是

  • 能够将生产数据库中的数据匿名化为我们可以存储在Git中的状态。这种同步应该是在我们想要的情况下进行的,所以明确不是每次我们想要运行测试的时候都要进行同步。我们不能手动写插入数千行的数据。
  • 在每次测试运行之前,将数据库重置为存储保存的方法。

我们应该选择哪种内存数据库的方式?

c# asp.net-core testing entity-framework-core in-memory-database
1个回答
1
投票

按照OP的要求,把我的评论移到回答上。

根据你发布的EF Core链接,关于测试(https:/docs.microsoft.comen-usefcoremiscellaneoustesting。)很明显,使用内存(甚至SQL Lite)并不是 "推荐 "的,只是因为你测试的东西不能反映你的生产场景。也许有人会说,你不应该测试db的实现,但实际上,大多数时候这是必要的。例如,我想测试我创建的一个View是否返回了预期的结果,或者正确地生成了一个报表,所以我认为像OP问的那样使用一个完整的fletched SQL Server是一个合理的观点。另外一点是,使用像SQL Lite这样的东西并不能很好地支持你使用EF的所有迁移。例如我在创建索引时已经遇到了问题。

继续说下去。你可以尝试解决这个问题的一个方法是使用Docker容器。你可以在Linux容器中运行SQL Server 使用Docker运行SQL Server容器镜像. 这个想法是,你可以创建一个自定义的图像,基于SQL Server和图像内,你把你的5000行(或任何你想要的数据),建立和推送即用的图像到docker注册表。

然后在你的系统CI期间,你想用预期的数据运行你的测试,你启动你创建的镜像的docker容器,让你的测试连接到那个SQL Server实例(只需要将端口映射到主机,通常是1433)。这样你就可以保证你的测试总是以相同的数据集启动。

至于构建映像本身,你可以通过多种方式进行。你可以有一个CI本身来创建映像。它可以从某个地方获取数据,或者让一个小程序为你生成数据并将其放在容器内。它可以是一个.bak文件,也可以是一个SQL脚本,里面有一堆由你的程序生成的Inserts。然后当你想让你的映像有 "新 "数据时,你需要做的就是运行CI构建。你可以在Docker镜像中添加标签,以确保你可以针对新旧版本的数据运行测试,这很酷。

这也是需要考虑的事情。当你的数据库发生变化时,你可能还需要更新镜像(迁移),但你也可以通过总是从最新版本的模式中创建镜像,或者通过使用 MigrateAsync 在CI过程中生成图像。当然,这很大程度上取决于你的DB改变的频率。

我为Postgres数据库做了类似的事情,这些链接帮助我开始了工作。对于SQL Server来说也应该是非常相似的。

Docker Tip #79: 在Docker镜像中保存Postgres数据库。

构建包含数据的Docker Image Postgres

© www.soinside.com 2019 - 2024. All rights reserved.