【发布时间】: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