TransactionScope doesn#39;t rollback in per-test TearDown for integration testing using NUnit and TestServer(使用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不会在每个测试拆卸中回滚的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:使用NUnit和TestServer进行集成测试时,TransactionScope不会在每个测试拆卸中回滚


基础教程推荐
- 如何在 IDE 中获取 Xamarin Studio C# 输出? 2022-01-01
- SSE 浮点算术是否可重现? 2022-01-01
- 如何激活MC67中的红灯 2022-01-01
- 将 XML 转换为通用列表 2022-01-01
- 有没有办法忽略 2GB 文件上传的 maxRequestLength 限制? 2022-01-01
- MS Visual Studio .NET 的替代品 2022-01-01
- 将 Office 安装到 Windows 容器 (servercore:ltsc2019) 失败,错误代码为 17002 2022-01-01
- c# Math.Sqrt 实现 2022-01-01
- 为什么Flurl.Http DownloadFileAsync/Http客户端GetAsync需要 2022-09-30
- rabbitmq 的 REST API 2022-01-01