问题描述
常规
我正在使用TestHost
来实现API的集成测试。业务逻辑被包装到TransactionScope
内的一个动作中,如下所示:
[ApiController]
public class DomainController : ControllerBase
{
[HttpPost("test")]
public async Task<IActionResult> test()
{
// Debugging stuff to demonstrate the issue
Console.WriteLine($"Transaction is {(Transaction.Current != null ? "NOT " : "")}null");
var curr = Transaction.Current ?? throw new Exception();
// Actual business logic
using (var scope = new TransactionScope(TransactionScopeOption.required,TransactionScopeAsyncFlowOption.Enabled)
{
// ...
}
}
}
现在有一个集成测试(我正在使用NUnit),它可以设置测试主机,创建客户端,填充测试数据库,创建外部Transaction
,调用API,验证测试数据库状态,等等:
[Test]
public async Task test()
{
using (var scope = new TransactionScope(TransactionScopeOption.required,TransactionScopeAsyncFlowOption.Enabled))
{
Console.WriteLine($"Current tran is {(Transaction.Current != null ? "NOT " : "")}null");
var response = await _client.PostAsync("/test");
response.EnsureSuccessstatusCode();
}
}
问题
使用 .NET Core 2.2 -两项工作正常:
- 我在测试输出中看到来自API动作的调试消息。
- 内部API动作中,存在外部环境事务(
Transaction.Current
不为null),因此new TransactionScope(TransactionScopeOption.required,...)
加入了该事务。可以。
现在,迁移到 .NET Core 3.1 后,以上所有方法均无效。实际上,为什么测试框架没有在API动作中选择Console.WriteLine
却是非常有趣的,但是最重要的是事务。
我对正在发生的事情一无所知,我认为这与更新的TestHost
或新的通用Web主机无关吗?如何从测试中获得内部事务连接外部事务的预期结果?
详细信息
- 两个版本都使用相同软件包的相同版本。例如。测试项目取决于:
- nunit 3.12.0
- NUnit3TestAdapter 3.17.0
- Microsoft.NET.Test.Sdk 16.7.1
-
已迁移版本的区别在于更新
Startup.cs
,主要是行services.AddControllers() ... .AddApplicationPart(typeof(Startup).Assembly);
-
我尝试使用.NET Core 3.1创建
TestHost
的两个版本-结果是相同的。较旧的版本为new WebHostBuilder()
,另一个为new HostBuilder().ConfigureWebHost()
。 -
我现在无法使用.NET Core 3.0绑定进行尝试,但我想这应该是相同的问题。
更新
此github issue似乎与之相关,建议的修复方法是设置Server.PreserveExecutionContext = true;
。
就我而言,它解决了第一点-我能够按预期看到调试消息。但是,测试期间会发生另一个错误-The platform does not support distributed transactions
。不过,我想知道是什么导致它将事务升级为分布式事务...
无论如何,我决定采用另一种方法,只是使用旧的简单ADO.NET对测试进行自我清理-只是从所有表中删除。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)