使用NUnit和TestServer进行集成测试时,TransactionScope不会在每个测试拆卸中回滚

编程入门 行业动态 更新时间:2024-10-25 10:24:42
本文介绍了使用NUnit和TestServer进行集成测试时,TransactionScope不会在每个测试拆卸中回滚的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 方案

我在ASP.NET Core 2.0上有一个API,它使用EF Core与MS SQL数据库集成。现在,我正在尝试使用NUnit和TestServer为其设置集成/API测试。问题是我需要将每个测试配置为‘隔离’,所以基本上它应该在自己之后清理(回滚)数据库。由于数据库的复杂性(需要考虑大量遗留问题,例如触发器等),我无法使用薪酬事务来实现预期结果。

SUT API安装

以下是我正在尝试测试的API示例:

// GET api/values [HttpGet] public async Task<IActionResult> Get(string dataName1, string dataName2) { using (var scope = CreateScope()) { await _service.DoWork(dataName1); await _service.DoWork(dataName2); scope.Complete(); } return Ok(); } DoWork()方法基本上查找给定的传递参数的实体,并递增其另一个属性。然后只需调用SaveChanges()。 这里CreateScope()是一个助手方法,它返回TransactionScope:

的实例 return new TransactionScope( TransactionScopeOption.Required, new TransactionOptions() { IsolationLevel = IsolationLevel.RepeatableRead }, TransactionScopeAsyncFlowOption.Enabled ); 集成测试设置 [TestFixture] [SingleThreaded] [NonParallelizable] public class TestTest { private TransactionScope _scope; [Test] public async Task Test11() { _scope = CreateScope(); var result = await Client.GetAsync("api/values?dataName1=Name1&dataName2=Name2"); Assert.DoesNotThrow(() => result.EnsureSuccessStatusCode()); _scope.Dispose(); _scope = null; } }

这里的Client是利用Microsoft.AspNetCore.TestHost.TestServer创建的HttpClient的一个实例,CreateScope()方法实际上与接口中相同。 这个简单的例子运行得很好--通过调用_scope.Dispose(),我的sut API所做的更改被成功回滚,并且数据库返回到它的‘CLEAN’状态。

问题

现在,我要将与范围的创建/回滚相关的逻辑移到测试方法之外,并将其放入SETUP/TEARDOWN中,以便自动处理所有测试。

[SetUp] public async Task SetupTest() { _scope = TransactionHelper.CreateScope(); } [TearDown] public async Task TeardownTest() { _scope.Dispose(); _scope = null; } [Test] public async Task Test11() { var result = await OneTimeTestFixtureStartup.Client.GetAsync("api/values?dataName1=Name1&dataName2=Name2"); Assert.DoesNotThrow(() => result.EnsureSuccessStatusCode()); }

但由于某种原因,它无法工作(我可以在测试运行后看到数据库中的修改),并且我无法弄清楚它。

为什么?我错过了什么?

注意:两个测试版本都成功通过。

推荐答案

可能的解决方案是从[SetUp]和[TearDown]中删除async。

解释:

使用TransactionScopeAsyncFlowOption.Enabled时,事务作用域应该跨线程延续流动,但由于_scope是在async设置和拆卸中创建和处置的,因此它是在其他线程上下文(不是同一线程延续)中创建和处置的。SUT内的scope不参与此上下文,因此不起作用

更多推荐

使用NUnit和TestServer进行集成测试时,TransactionScope不会在每个测试拆卸中回滚

本文发布于:2023-11-07 00:45:26,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1565096.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:测试   在每个   TestServer   NUnit   TransactionScope

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!