Entity framework core 如何包装在数据库事务中使用TestServer的集成测试?
使用xUnit和Microsoft.AspNet.TestHost中的Entity framework core 如何包装在数据库事务中使用TestServer的集成测试?,entity-framework-core,xunit,Entity Framework Core,Xunit,使用xUnit和Microsoft.AspNet.TestHost中的TestServer,如何将每个测试包装在一个数据库事务中,以便在测试后回滚 下面是我如何创建TestServer: TestServer = new TestServer(TestServer.CreateBuilder() .UseStartup<Startup>()); 我可以将DbContext从服务中拉回来,并在Startup类中存储一个静态引用,但这似乎很有技巧。是否有任何方法可以实例化DbC
TestServer
,如何将每个测试包装在一个数据库事务中,以便在测试后回滚
下面是我如何创建TestServer
:
TestServer = new TestServer(TestServer.CreateBuilder()
.UseStartup<Startup>());
我可以将DbContext
从服务中拉回来,并在Startup
类中存储一个静态引用,但这似乎很有技巧。是否有任何方法可以实例化DbContext
,在这里我创建TestServer
,并让web应用程序使用它,而不是Startup
类中的一个
编辑:我尝试实例化另一个
DbContext
实例,在其中创建TestServer
,并在每次测试之前使用该上下文删除和重新创建数据库,但这会给每个测试的运行时间增加大约10秒。一些建议:最简单的方法是在测试结束时销毁测试数据库,并为每个测试运行重新创建数据库。这确保了测试污染时不会出现延迟测试
但既然您问了如何扩展Xunit,这可以通过扩展Xunit来实现。Xunit允许您定义自定义测试用例和测试运行程序。完整的答案很难包含在SO答案中。最简单的解决方案使用环境事务。(危险!环境事务可能很棘手。)Xunit有一个用于回滚事务的自定义BeforeAfterTestAttribute的示例。要使用环境事务,请关闭在存在环境事务时引发的默认EF设置。(optionsBuilder.UseSqlServer().SuppressAmbientTransactionWarning()
)
一个更复杂但更好的解决方案是重写XunitTestCaseRunner
,并向每个测试用例中注入一个事务,确保在每个测试结束时回滚
此外,EF文档还提供了使用InMemory提供程序进行测试的示例。你可能会发现这很有用。
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<TrailsDbContext>(options => options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));