C# 无法捕获xUnit中的InvalidOperationException
在过去的一个小时里,我一直试图通过以下测试,但似乎无法成功:C# 无法捕获xUnit中的InvalidOperationException,c#,.net-core,entity-framework-core,xunit,C#,.net Core,Entity Framework Core,Xunit,在过去的一个小时里,我一直试图通过以下测试,但似乎无法成功: [事实] 公共异步void TestDetachedRecordsRentUpdatedWithoutIDS()的 { var options=new DbContextOptionsBuilder() .UseInMemoryDatabase(数据库名称:“不能使用银行信息更新分离的客户”) .选择; int clientID,bankInfoID; 使用(var context=newclientcontext(选项)) { va
[事实]
公共异步void TestDetachedRecordsRentUpdatedWithoutIDS()的
{
var options=new DbContextOptionsBuilder()
.UseInMemoryDatabase(数据库名称:“不能使用银行信息更新分离的客户”)
.选择;
int clientID,bankInfoID;
使用(var context=newclientcontext(选项))
{
var服务=新的ClientService(上下文);
var bankInfo=new bankInfo{RoutingNumber=“12345”};
var client=new client{FirstName=“Javier”,LastName=“Garcia”,BankInfo=BankInfo};
等待服务。保存(客户);
clientID=client.ID;
bankInfoID=client.BankInfo.ID;
}
使用(var context=newclientcontext(选项))
{
var服务=新的ClientService(上下文);
var bankInfo=new bankInfo{RoutingNumber=“Modified”};
var client=new client{ID=clientID,FirstName=“Modified”,BankInfo=BankInfo};
尝试
{
等待服务。保存(客户);
}
捕获(System.InvalidOperationException ex)
{
var expected=“实体类型“BankInfo”上的属性“ID”是键的一部分,因此无法修改或标记为已修改。”;
Assert.Contains(应为,例如Message);
}
}
}
我发现的问题是,我似乎无法捕捉异常。这是我每次运行测试的结果:
为了提供一点额外的上下文,当调用ClientService::Save
时,它会调用一个名为handledisconnectedenties
的方法,该方法在以下行运行时启动:
94: _context.Entry(existingClient.BankInfo).CurrentValues.SetValues(client.BankInfo);
我确实理解异常的本质,但我不理解为什么我的测试无法捕获它。非常感谢您的任何见解 该问题是由于测试定义的
异步无效
public async void TestDetachedRecordsArentUpdatedWithoutIDs() { ...
异步void方法具有不同的错误处理语义。当从异步任务
或异步任务
方法中抛出异常时,将捕获该异常并将其放置在任务对象上。对于async void
方法,没有Task
对象,因此从async void
方法抛出的任何异常都将直接在SynchronizationContext
方法启动时处于活动状态的SynchronizationContext
上引发
无法使用Catch捕获异步Void方法的异常
比如说
private async void ThrowExceptionAsync()
{
throw new InvalidOperationException();
}
public void AsyncVoidExceptions_CannotBeCaughtByCatch()
{
try
{
ThrowExceptionAsync();
}
catch (Exception)
{
// The exception is never caught here!
throw;
}
}
将测试改为使用任务
public async Task TestDetachedRecordsArentUpdatedWithoutIDs() {
//...
}
由于测试定义的
异步无效
,请参考问题
public async void TestDetachedRecordsArentUpdatedWithoutIDs() { ...
异步void方法具有不同的错误处理语义。当从异步任务
或异步任务
方法中抛出异常时,将捕获该异常并将其放置在任务对象上。对于async void
方法,没有Task
对象,因此从async void
方法抛出的任何异常都将直接在SynchronizationContext
方法启动时处于活动状态的SynchronizationContext
上引发
无法使用Catch捕获异步Void方法的异常
比如说
private async void ThrowExceptionAsync()
{
throw new InvalidOperationException();
}
public void AsyncVoidExceptions_CannotBeCaughtByCatch()
{
try
{
ThrowExceptionAsync();
}
catch (Exception)
{
// The exception is never caught here!
throw;
}
}
将测试改为使用任务
public async Task TestDetachedRecordsArentUpdatedWithoutIDs() {
//...
}
Reference您确定在try-catch块中的保存出错吗?您有另一个等待服务。保存(客户端);上面的内容不是由try-catch处理的。也许是那个人扔了所以你的测试从来没有断言…?@marko是的。在第二次调用中,我尝试将ID添加到
bankInfo
记录中,异常将停止触发,因此我确定它是环绕try-catch的ID。您确定try-catch块中的保存出错吗?您有另一个等待服务。保存(客户端);上面的内容不是由try-catch处理的。也许是那个人扔了所以你的测试从来没有断言…?@marko是的。在第二次调用中,我尝试将ID添加到bankInfo
记录中,异常将停止触发,因此我确定它是围绕try-catch的ID。