【问题标题】:Transactional Integration Testing ASP.Net Core and Entity Framework Core事务集成测试 ASP.Net Core 和 Entity Framework Core
【发布时间】:2018-05-24 05:47:31
【问题描述】:

我很好奇是否有人走上了使用 aspnet 和 ef core 进行事务集成测试的道路?我希望能够一直执行到数据库的完整集成测试(不使用内存数据库)。有两个问题:

  • 测试可能有副作用,但应该单独运行,因为副作用可能导致其他测试失败。我不希望开发人员在每次测试后都需要编写过多的清理代码。
  • 我可以在每次测试运行时拆除并重新创建数据库,但是随着测试计数开始达到 100 次,运行测试变得难以忍受。

我想将测试包装在事务中 (_dbContext.Database.BeginTransactionAsync())。问题是我从中得到的 DbContext:

_server = new TestServer(builder);
_services = _server.Host.Services;
_dbContext = (AppDbContext)_services.GetService(typeof(AppDbContext))

与由 AspNetCore 中间件解析的范围不同(因此是不同的实例)。因此,只有测试代码是事务性的,而不是 TestServer 执行的任何代码。我曾考虑在 TestStartup 类中使用一些测试中间件,将 API 代码包装在事务中,但问题是它会在测试评估它之前被释放/回滚。考虑以下用例:

  • 发送 POST 创建资源
  • 断言 dbContext 包含资源

在这种情况下,测试需要访问测试服务器使用的相同 dbContext 实例。 我尝试了一些使用AsyncLocal 传递上下文的hacky 方法,但没有成功,所以我只尝试使用一个简单的static 成员。 但是,这也不起作用,因此测试应用和TestServer 之间似乎存在一些 AppDomain 隔离。 我很好奇有没有人走这条路,如果有,他们想出了什么?

【问题讨论】:

  • 为什么不直接使用Microsoft.EntityFrameworkCore.InMemory 进行测试?
  • 如前所述,我需要一直到数据库。我们的应用正在使用多个数据库提供程序(MS SQL Server 和 PostgreSQL),我们还希望验证可以特定于提供程序的迁移。
  • 那么,您想以可能导致其他测试失败的方式更改数据库并且您不想编写清理/恢复代码?
  • 是的。同时运行的测试可能会相互影响。或者它们可能具有阻止其他测试假设它们在干净的环境中运行的副作用。我希望测试在不产生副作用的事务中运行。这不是一个新概念,并且已经存在一段时间了(参考事务性固定装置/测试)。测试不应该关心它们是否会影响其他测试。
  • ASP.Net Core 的 DI 单例不是传统单例模式的实现(即每个应用程序域一个实例)。相反,它是每个IServiceProvider 实例的一个实例(在这种情况下,使用TestServer 创建)。这是可行的,因为每个测试都会收到一个唯一的 TestServer 实例。

标签: c# asp.net asp.net-core .net-core entity-framework-core


【解决方案1】:

刚刚结束这个问题。解决方案是将 DbContext 注册为测试启动类中的单例。所以,在测试中:

services.AddDbContext<HostContext>(Configure, ServiceLifetime.Singleton);

但是,在应用程序中它会被注册为:

services.AddDbContext<HostContext>(Configure, ServiceLifetime.Transient);

更新

更完整的答案已在此处发布http://nance.io/leveling-up-your-dotnet-testing-transactional-integration-testing-in-asp-net-core/

【讨论】:

  • 这种方法有缺点。想象一下,在运行应用程序时,您的实体上的导航属性为空,并且在访问它时会引发空指针异常。这可能不会在测试中检测到,因为在 Singleton DbContext 中,可能会从之前记住该实体并正确设置导航属性。所以测试可能会给你错误的图片。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-16
  • 1970-01-01
  • 2018-08-27
  • 2023-01-31
  • 1970-01-01
相关资源
最近更新 更多