ASP.Net Core和Entity Framework Core事务集成测试

3

我想知道有没有人尝试过使用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隔离。 我很想知道是否有人已经走过这条路,如果有的话,他们得出了什么结论?


2
为什么不直接使用 Microsoft.EntityFrameworkCore.InMemory 进行测试呢? - Camilo Terevinto
那么,您想以可能导致其他测试失败的方式更改数据库,并且不想编写清理/还原代码? - Camilo Terevinto
请查看此链接:https://charleskorn.com/2016/03/30/faster-database-testing-with-snapshots/ - Ewan
你尝试将你的dbContext注册为Singleton了吗? - agua from mars
1
ASP.Net Core的DI Singleton并不是传统单例模式(即每个应用程序域一个实例)的实现。相反,它是每个IServiceProvider实例(在这种情况下,使用TestServer创建)的实例。这是因为每个测试都会收到一个唯一的TestServer实例。 - jaredcnance
显示剩余4条评论
1个回答

2

3
这种方法有缺陷。想象一下,当运行应用程序时,您的实体上具有空导航属性,并且在访问它时会抛出空指针异常。这可能在测试中无法检测到,因为在单例 DbContext 中,该实体可能已经从之前记忆中,并且导航属性已正确设置。因此,测试可能会给您错误的图片。 - Aleksa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接