如何在数据库事务中包装使用 TestServer 的集成测试



使用 xUnit 和 Microsoft.AspNet.TestHost 中的TestServer,如何将每个测试包装在测试后可以回滚的数据库事务中?

以下是我创建TestServer的方式:

TestServer = new TestServer(TestServer.CreateBuilder()
    .UseStartup<Startup>());

此处引用的Startup是 Web 应用项目中的Startup。在该Startup类的ConfigureServices方法中,我像这样添加 EF:

services.AddEntityFramework()
    .AddSqlServer()
    .AddDbContext<TrailsDbContext>(options => options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));

我可以拉回服务的DbContext并在Startup类上存储静态引用,但这似乎很笨拙。有什么方法可以实例化我创建TestServerDbContext,并以某种方式让 Web 应用程序使用它而不是 Startup 类中的应用程序?

编辑:我尝试实例化DbContext的另一个实例,在其中创建TestServer,并在每次测试之前使用该上下文删除并重新创建数据库,但这会增加大约 10 秒每个测试的运行时间。

一些建议:最简单的方法是在最后销毁测试数据库,然后为每个测试运行重新创建。这确保了没有挥之不去的测试间污染。

但是既然你问了怎么做,这可以通过扩展Xunit来完成。Xunit 允许您定义自定义测试用例和测试运行程序。完整的答案很难包含在 SO 答案中。最简单的解决方案使用环境事务。(危险!环境事务可能很棘手。Xunit 有一个回滚事务的自定义 BeforeAfterTestAttribute 示例。https://github.com/xunit/samples.xunit/tree/master/AutoRollbackExample。若要使用环境事务,请关闭在存在环境事务时引发的默认 EF 设置。(optionsBuilder.UseSqlServer().SuppressAmbientTransactionWarning()(。

一个更复杂但更好的解决方案是覆盖XunitTestCaseRunner并将事务注入每个测试用例,确保在每个测试结束时回滚。

此外,EF 文档还提供了使用 InMemory 提供程序进行测试的示例。您可能会发现这很有用。"在内存中测试:EF Core 文档">

相关内容

  • 没有找到相关文章

最新更新